これは、traP Advent Calendar 2016 4日目の記事です。
1、導入っぽいやつ
こんにちは、hukuda222です。さて、皆さんは今日12月4日がなんの日かご存知でしょうか?
海軍記念日だったり、血清療法の日だったりもするんですが、僕が言いたいのはそうではなくて
そうです、本日は大人気四コマ漫画『ご注文はうさぎですか?』のヒロイン、香風チノちゃんの誕生日です!
僕にとっては、今日はクリスマスよりも何千倍も大事な日なわけでして、traPの部員らしくチノちゃんが主役のゲームを作ろうと思い至ったわけです。
さて、どんなゲームにしましょうか。
クリスマスをテーマにしたノベルゲーム、ラビットハウス経営シミュレーションゲーム、脱出ゲーム、シューティングゲーム...etcと色々考えていたわけですが、最近流行りのVRの波にのるべく、VRゲームを作りたいと思います。
タイトルの"ウサギ"はそんなに深い意味はないんですが、「猫でも」C言語ができるのなら猫より知能で劣るウサギでもできるくらい簡単だという意味合いがあったりなかったりします。
2、A-Frameっていうのを使うよ
さて、チーム制作の方で、Three.jsというWebGLを使いやすくしたツールを使いそうなので、その界隈の記事やサイトをいくつか読んでいると"A-Frame"というMozilla VRチームがリリースしたバーチャルリアリティのフレームワークを見つけました。
公開は一年ほど前になるのですが、流行りのVRゲームを申し訳程度のHTMLとJavaScriptの知識で制作できるというスグレモノです。
なんと、この下のコードを適当なhtmlファイルにコピペするだけでブラウザで動くVRゲームを作ることができます。普通、VRゲームはUnityなどの結構高いスペックのPCを要求するツールを使うのが一般的なので、これは便利です。
<!DOCTYPE html>
<html>
<head>
<script src="https://aframe.io/releases/0.2.0/aframe.js"></script>
<head>
<body>
<a-scene>
<a-box color="red" rotation="0 0 0" position="0 0 0" width="1" height="1" depth="1"></a-box>
</a-scene>
<body>
</html>
(デモ) https://hukuda222.github.io/a-frame/cubedemo.html
これだけで3D描画できるだけでも十分すごいのですが、クリックしながらマウスを動かすと視点もそれに合わせて動いてくれます。また、WASDキーでカメラを操作できます。
さらにさらに、このページをスマートフォンで開き、右下の怪しげなアイコンをタップするとVR対応画面になります。
amazonのスマホ装着用のVRゴーグルをつけるといい感じに立体的に見えると思います。
Chromeなどのブラウザだと、ローカルの画像を使うときにエラーが出ることがあります。下のリンクを参考にコマンドでChromeを起動させれば基本的には大丈夫なのですが、面倒ならFireFoxで開発するのもアリだと思います。
chromeでXMLHttpRequestをローカルのファイルで行う方法
公開するとA-Frameに対応しているブラウザなら動くので心配ないです。
(僕が動作確認したのは、Chrome、FireFox、Opera、Safariです)
3、とりあえず制作開始
はい、制作開始です。FPSだとチノちゃんの手しか見えないので、TPSっぽくチノちゃんの後ろ姿を見ながらできるゲームにしたいと思います。ここで、銃とか持たせてもいいのですが、敵を出すとなるとAIとかも考えないといけませんし、3Dの当たり判定なども厳密に作る必要が出てきます。
そんなわけで、今回はチノちゃんが迷路に挑戦するゲームにしたいと思います。チノちゃんは原作でもクロスワードや知恵の輪に興じているのでイメージにもぴったりです。
1、そもそもどういう感じで記述するの?
HTMLで物体を作っておいて、それにidをつけてjavascriptで動かしたり変形させたりする、というのが基本的なA-Frameの使い方です。もちろん、javascriptで新たに
position = x+" "+y+" "+ zみたいな書き方も可能です。
もちろんidが設定できるので、
$("#test").attr("color","#FFFFFF");
のように後から変更するのも簡単です。詳しくはMozilaのページを見るのがいいと思います。
2、3Dモデルのモーションってどうするの?
ここが一番最初の関門でした。結論から言うと、3Dモデルの読み込みは.dae と .obj形式が使えるのですが、ボーンを用いたモーションには対応していません。チノちゃんの.mmdデータと歩行モーションの.vmdデータを使わせていただくつもりだったのでいきなり問題発生です。
ところで、歩いているチノちゃんを後ろから見た画像を画面の中心に貼り付ければそれっぽく見えないでしょうか?
この時点でA-FrameでFPSを作る方法を探してこのページにたどり着いた方がブラウザバックしている様子が目に浮かびますが、続けます。
さらに、gifを物体に貼り付ける方法はあるのですが、物体に貼り付けると、背景を透過したgifを透明な物体に貼っても、透過してくれなくなります。プレイヤーのキャラが完全な四角形や円ならそれでもいいのですが、今回は使えなさそうです。
そんなわけで、普通に透過したpngファイルを紙芝居形式に表示することで歩行モーションを再現しました。
<a-assets>
<img id="image" src="chino.png" >
</a-assets>
<a-image id="player" src="#image" position="0 0 0" rotation="0 0 0"><a-image>
3、視点(カメラ)を回したい
<a-entity id="camera" position="0 0 2" rotation="0 180 0">
<a-camera near="0.01" far="10000" fov="40" wasd-controls-enabled="false"></a-camera>
</a-entity>
こんな感じに
wasd-controls-enabledは、デフォルトで実装されているWASDで視点(カメラ)を動かせる機能をそのままにしておくかどうかです。今回は十字キー操作にしたかったのでfalseにしています。
4、スマホ操作に対応させたい
マジレスすると、いくら対応させたところで絶対操作しにくいです。
ですが、一応VRゲームを作ろうというコンセプトなのでスマホを頭に装着した状態でも操作ができるようにしましょう。
スマホを頭につけている状態ではタップ機能が使えません。また、ヘドバンのような動きを強要することになるので加速度センサーを利用するのも難しそうです。
そこで今回は、サイト起動時から、スマホがどのくらい回転したかでキャラの向き操作できるようにしました。(前方には勝手に進むようにしました)
if (navigator.userAgent.indexOf('iPhone') > 0 || navigator.userAgent.indexOf('iPad') > 0 || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('Android') > 0) {
Dir.front = true; //スマホだったら勝手に前進する
}
window.addEventListener('deviceorientation',function(event) { //デバイスの傾きや方角の値が変化したとき
let CameraRota = $("#camera").attr("rotation"); //カメラの位置を取得
if (Math.pow(LastDir - event.alpha, 2) > 25) {
CameraRota.y = Math.floor(event.alpha);
LastDir = Math.floor(event.alpha);
}
$("#camera").attr("rotation", (CameraRota.x) + " " + CameraRota.y + " " + CameraRota.z);
});
小刻みに動くととても見辛いので、ある程度大きく回転したら視点を更新するようにしました。
LastDirには最後に動いた後の角度が入っています。
また、旋回以外の動作をさせるのは難しいので勝手に前進するようにしました。
スマホに対応させるときに一番面倒なのはデバッグでした。
他にいい方法が思いつかないので、GitHub( https://github.com/)のサービスの一つである、github pagesというのを利用しました。
これはとても使いやすいのでオススメです。
gitに新しく、gh-pagesという名前のブランチを作り、そこにコミットするだけです。
少し経つと、https://(ユーザー名).github.io/(プロジェクト名)/(htmlのパス)に自分が作ったページが表示されます。
4、完成品
https://hukuda222.github.io/a-frame/
一応、それっぽいものはできました。5×5マスの迷路で、ピンク色の立方体がゴールです。
迷路の生成は棒倒し法で実装しました。
PCだと、十字キーの左右で旋回し、
スマホだと、左右に回転させることで旋回させることができます。
ソースコードはこんな感じです。本当はここにペタッと貼りたかったのですが、インデント調整するのが面倒だったので、リンクから見てください。
https://github.com/hukuda222/a-frame/blob/master/index.html
座標軸が、右向きに+x軸、上向きに+y軸、手前方向に+z軸があるというのを意識すれば、三角関数がちょっと見づらい以外は読めるはずです。
5、感想
200行ちょっとのコードでここまでそれっぽいものが作れるのは、かなり有用だと思います。
まだまだ自由度が低く、ボーンのモーションなどできないことが多いですが、現状は開発途上のものなので、今後、より主流のVRゲーム開発ツールになる可能性を秘めています。
JavaScriptやJQueryの入門に使えるくらいの手軽さなので、気が向いたときにでも遊んで見てはいかがでしょうか。
さて明日は、dermas氏とlong_long_float氏の記事です。
僕はネタにわか技術枠ですが、ガチ技術枠からガチネタ枠まで色々あるので、明日以降のアドベントカレンダーも是非是非見てくださいね。
ちなみに、12月5日はアイマスの水野翠の誕生日です。
6、使わせていただいた素材・参考にしたサイト
http://www.nicovideo.jp/watch/sm28053941 (香風チノのMMDモデルの配布動画)
traPのではないですが、去年のアドベントカレンダーにA-Frameについての記事がいくつかありました。