Google

2014年1月28日火曜日

HTML5で3Dゲーム:サイズと開発ツール等

ネタとなる情報はだいたい揃ったので今回はサイズとツールの話を。

言うまでもなくファイルサイズはゲーム開始までの時間に直結します。
ロード時間のベンチマークはFireBugやchrome等のDevelopper Tool等で確認できますが、無駄な送受信を省くためには最小限のローディングが望ましい訳です。

chromeの場合メニューの「ツール」→「デベロッパツール」で開きます。
Networkタブでローディング状況が確認可能です。
今回のゲームの場合は仕組みを以下のように分割したため、それぞれでまとめる必要がありました。

  • ゲーム本編用
    • enchant.js用にスプライト化
  • タイトル、GUI等
    • CSSスプライト化

分割した理由ですが実装作業を分担する必要があった点や、enchant.jsで全てを賄うとロジックが煩雑になるという点でしょうか。
全部enchant.jsで作っても勿論問題はありません。

そして、実際のサイズ削減手段ですが、enchant.jsで使われるスプライト構成は手動でした。
CSS用はこのブログでも紹介させて頂いたことがある「TexturePacker」に任せました。
オプションにはCSS用もあり、アトラスとCSSファイルを書き出してくれるため、非常に役立ちます。

Unityでお世話になってますが、CSSでもそのまま行けます。
ネタも大分出し尽くしたので、次でこの記事は最後です。
今までのまとめや細かい部分について補足する予定です。

2014年1月24日金曜日

HTML5で3Dゲーム:壁床3D

前回は当たり判定の記事でした。

今回は壁床ですが、ここまで書いてて大事な点について記載することを忘れていました。
計算がすべての擬似3Dゲームにおいては、主人公や物体の大きさや1点透視法でのカメラ角度やその他見え方等の表現等に関して、予め大きさや距離等を決めておかないと実現ができません。
当たり判定にも絡むこれらの話についてどう決定しどう対処したか?という話を書いておきます。

お忘れの方もいらっしゃるかと思いますが、元々このゲームはUnity版と同時に開発し、Unity版と全く同じゲーム性を求められていました。
この検証のゴタゴタの裏でUnity版が同時進行していたのですが、同時進行しているが故に可能だった重要なポイントがあります。

1つめとしてUnity版及びHTML5版のどちらも「大きさや距離等を統一」することにした点。
(同じゲーム性ですし当然っていえば当然なんですが)
横に2列あるマスの1個1個の大きさについては1mx1mという基準を設け、アイテムまたは障害物もこれに習い最大で1m立方体ということになりました。
主人公の当たり判定も当然その中に収まる範囲で、ということになります。
焦点は例の透視法計算の関係からゼロでしたが、1マス進行は1m、物体も1m、とにかく基準はすべて1mという物差しを決めたのです。

これはUnityのプリミティブ機能で作成できる「Cube」がこの1m立方体という点も大きく関係していました。
さっと作れて、かつ取り込んだ3Dモデルのサイズが拡大縮小等で変動しても簡単に比較できますし。

このCubeが立方体。
グリッドもそうですが、角度によって見えない時もあるし、、
さらに大事なのは次の点。
Unity版/HTML5版は視点もカメラも一緒、距離も大きさも一緒なので、Unity上で表示した画像はそのままHTML5に持ってきても同じに見えるはず。
これを最大限に活用するためにこんな裏技?を使う事になりました。
  1. Unity上で指定位置にアイテム等のモデリングを表示
  2. その状態の画像をキャプチャ
  3. CSSスプライト化し、HTML5でリソースとして再利用
まあ、なんといいますか、、、、自分で言うのもなんですが酷いですよね。
もはや透視法の計算ですらありません。
とはいうものの、接近してポリゴンの見え方がおかしくなる問題もこれでほぼ解決になるため利用価値は大いにありました。
デメリットとしては、戻りが発生した場合にUnity上の作業がやり直しになる点ぐらいでしょうか。
前々回の記事にあった透視法の実装は、最終的にUnityの力を借りて実現したというのがこの話のネタの一つになります。


さて、これを念頭において頂いて、改めて壁と床の話を。
以前の記事で書いたように、Three.jsなしでどう表現するかについて何度か試行錯誤をしていました。
往年のセガ名作ゲームのように遠い位置からタイルをガンガン並べる方法も考えましたが、枚数が多くなれば当然処理が重くなりますし、このタイプのゲームには今ひとつあっていません。
なにせ、斜めのパネルも位置による角度の計算があるため、その部分の処理も面倒です。

そしてここでもまたひどい決断をすることになってしまいました。
結論から言うとUnityや3Dツールで道路をキャプチャし、CSSスプライトとして使用するという方法を採用したのです。
要は3Dツール上のカメラやサイズなどを一致させ、アルファレンダリングをしてそれを動画キャプチャし、フレームレートに応じた分割を行うという、、、、笑ってやってください。

方法自体も酷いですが、これをやった場合負荷以外に心配になるのはファイルサイズでしょう。
某OSの640x960が基準の世界で、画面の半分以上は締めると思われる壁床の領域全てにアニメーションをしたら、まずサーバ負荷的が重くなり、ロードからゲーム開始までの時間が遅くなってしまいます。
しかしここは以下のような対処でなんとかなりました。
  • ホーム画面登録から起動する方式を適用することで、画面全体を320x480にする
  • 単純な画像の床にする
    • (某セガ体感ゲーム系のようなシンプルタイプ)
  • 色数を64色で構成しgifとして扱う
  • 移動速度(ゲーム難易度)と相談し、1サイクルに必要な枚数を調整する
上記の結果、床のスクロール専用画像を150KB未満まで落とすことができました。
1サイクルの枚数は秘密ですが、見栄え的にはなかなかでした。

担当CGデザイナーには無茶な注文と言われましたが、何と言われようとOKなものはOKです。
色数を落とした事でPhotoShopでのちまちま補正作業になってしまう点、バランス調整で速度の変更がどうしても必要になった場合に全てやり直しという点はデメリットですが、効果は絶大でした。

実際に使われているソースを出したい処ですが、ちょっと色々問題があるので今回はすみません。
参考となるよう、この記事のために簡単なデモを書いてみましたのでそちらでご勘弁を。
本番と違ってて申し訳ございませんが、やった内容はご理解頂けるかと思います。

パースも何も考えず縦に3つ重ねてみました。
本番とはかなり違いますが原理だけ一緒です。
ちなみに本番では縦横の分割はしませんでした。
今回のデモはこちらからどうぞ。
ブラウザサイズの大きさによって表示が拡大縮小するため、大きいサイズだと相当汚く見えます。

次回は速度も絡んだファイルサイズ等の話をします。

2014年1月22日水曜日

HTML5で3Dゲーム:当たり判定

今回はタイトル通りの話です。
当たり判定問題はどのFWを使おうが付いて回るもの。
一応曲りなりにもアクションゲーの分類に入る訳ですから、適当には出来ません。

主人公も接近する物体もどちらもペラ1枚の画像を使うと決めたので、システム上では矩形です。
これをそのままサイズで判定すると最も矛盾が生じるのは斜めの部分でしょう。

避けたつもりが当たってる、よくあるパターンです。
前回の記事の通り、最大で1つのエリアに4個の物体(アイテムor障害物)が存在するのですが、これらが同時に4個当たる仕組みにすると、それはそれで処理も煩雑になります。
まあ解決策は簡単で、当たり判定は皆さんおなじみの某定理を使って、円状にすることにしました。
もし判定を円ではなく球状にすれば3Dになりますが、元々が2D処理している点と見た目のズレが相まって無駄な努力になる可能性を考慮し、遊んで問題なければOKとする判断になりました。

その際に作ったのは簡単な円の概念を持つクラス、Circleです。

// サークルクラス
function Circle(x, y, r) {
    this.x = x;
    this.y = y;
    this.r = r;
}
// isHitメンバ関数です。引数はCircleインスタンスです。
Circle.prototype.isHit = function(doubt) {
    return ((doubt.x - this.x) * (doubt.x - this.x) + (doubt.y - this.y) * (doubt.y - this.y) < (this.r + doubt.r) * (this.r + doubt.r));
};

判定は数学でおなじみのアレです
このクラスは基準となるx,y位置と半径のrを持ち、定理を使ったヒット判定関数だけを実装しています。
主人公、障害物共にこの基本となる値を持たせるのですが、単にこのままでは使えません。
擬似的な球状を表現するため、本体の中心位置から遠ざかるほど半径を縮めて計算するようにしたわけです。

台北にあるダンパーの写真です。
いや、これを見せたい訳じゃなくて、円の判定がこのように折り重なってると
いうことを表現するために出したのですが、、、、
JavaScriptはENTER_FRAMEの間隔が保証されているわけでもないため、前回のフレームからの経過時間を元にし、移動した距離分の差分に丸め誤差を入れてあたったかどうかを判定するといった感じになります。
ここは入り組んでいるので部分的なサンプルが出しづらいためソース無しです、すみません。

分割すべき内容だったので、壁床の仕組みは次回書きます。

2014年1月20日月曜日

HTML5で3Dゲーム:Canvasで擬似3D

前回はCSS3Dに限界を感じ断念する話でした。
要は、この先の不安を考えれば2Dの方がはるかに安全という判断で、ここから大急ぎで3Dっぽいゲームを作ることになるのでした。
CSS3Dでのゲーム完成を期待されていた方は申し訳ございません。

なお、細かい判断理由は省きますが、幾つ買った候補のうち最終的に決まったのはenchant.jsでした。
当時は0.7.0になったばかりでしたが、CSS制御からCanvas制御になった事による高速化、日本語によるサポートやコミュニティの存在がなかなか大きかったと記憶しています。
欲を言えばPIXI.js位もう少しシンプルで高速だとさらに嬉しいですが、自分で作るしかない状況で無い物強請りは良く有りません。
逆に、当時日本語と文献や情報量で言えばこれしかなかったとも言えます。

という事で、再度これらの問題を2Dでどうにかする必要があります。
  • 接近する物体
  • 当たり判定
  • 床、壁
※1つ1つが長めの話になるので、今回は物体だけ解説です。

CSS3Dが使えないなら自前で3Dを表現するしかありません。
まず床と壁も含め、今回のゲームのような3Dの奥行きを2Dで表現するには「一点透視図法」という概念を使います。
簡単な図を以下に表示します。

拾い物の絵ですが、1点透視法ってざっとこういう事です。
点となって消える場所の消失点を軸にして物体の遠近を付ける方法で、絵描きさんなんかは良くご存知じゃないでしょうか。
この表示に関しては位置と焦点を元に画面上の位置を割り出す計算方法があります。


上図における焦点をZfとし、図の右上にあるP1の位置に存在する物体をスクリーン上で見る時のYsの位置は以下で割り出せます。

P2はP1よりも更に遠くにあるため、P1よりも下に小さく表示されるという事です。
しかし焦点の位置をゼロの中点と仮定すると、算出計算式がさらに簡単になったりするので、画面固定という条件をベースにそちらを使うことにしました。

先程のY計算だけでなく、X計算も簡易になります。
また、ペラペラの1枚板を接近させる想定なので、接近する物体の画像が持つx,y,width,heightは上記を元に算出できるという事になります。
問題は1つマスに何個最大障害物が存在するのか、というゲーム上の問題ですが、これは4個と決まりました。
最大で1マスに以下のように4つ並ぶ事になります。(田んぼの漢字じゃありませんw)

      □□
      □□

上の段を二段ジャンプで避けるという要求仕様もあったので、この程度で済む事になりました。
まあ、仕様が2列でも3段でも構造的に余り変化はありませんが。
今回の場合はそこそこ単純で、最小限でも4種類の画像(左上、左下、右上、右下)が1つのアイテムにつき必要となる訳です。
プロト作成実験で使うのはシンプルなこんな画像でした。

下段に来る物体のサンプル
こっちは上段。
ちなみにUnityで作成したBoxのキャプチャですw
そして先程の計算式を元に1フレーム毎に拡大し接近しているように見せかける訳です。
という事で今回公開するのはその際に作った第1弾のenchant.js版テストコードです。
画面は以下の様な感じ。

ひたすら接近する物体を眺めるだけの簡単なテストです。
上記デモを実際にブラウザで表示したい場合ははこちらからどうぞ。
ソースは拙いですがそのままご覧頂いて結構です。

ちなみに今回のデモで表示した物体接近は改良の余地が多々あります。
まず接近時の3D的な歪みがありません。
接近すれば視点移動で形状が変わるのですが、これは最終的に位置に応じた画像を差し替えることで対応しました。
先述の通り左右分の画像が無いですが、これも別途差し替えで対応できています。
前回触れたインスタンス管理やマップに関係する生成タイミング等も今回のデモでは出来ていませんが、これも最終版では全て使いまわし可能なように管理する形になりました。

また、この擬似接近の正体は、単にCanvas上で画像が拡大しているだけなので、物体の前後関係を管理してあげなければなりません。
このデモでは物体数が少ないため、あまり気にならないというだけの事です。

視点と画像の上下に関する当時の資料です。
こんな単純なこと考えてたことを思い出しました。

もし視点がぐりぐり変化するのなら全て計算しなければなりませんが、視点が固定であれば上図のように下段の物体が上段よりも上zのレイヤに来ることはありません。
また、各段の中では古いもの程zレイヤが上に来るため、その部分は単純です。
さらに影の有無はゲームに直結するため、これ以外にも影を描画する必要があります。上の影が下に被さってはまずいため、そこも物体の有無などを判断基準にして表示レイヤを管理する必要があります。

なお、enchant.jsが管理するimageはクラスにラップして管理を行う形になりました。
アイテム数が増えて結構大変にはなったのですが、とりあえずこれで物体はなんとかなったわけです。

次回は当たり判定と壁床の話です。

2014年1月18日土曜日

HTML5で3Dゲーム:CSS3Dの限界

今回はCSS3Dでプロトを作った後の話です。

前回開示した初回プロトですが、その後手を加え障害物・床・壁付きにしたバージョンをお客様にお見せし、そこそこうまくいってる感が出せたのは幸いでした。
この時、ターゲット最古機種でのfpsは57前後だった記憶があります。

が、ぬか喜びもつかの間、さらにプロトを細かく組んだ結果様々な問題がでてきたのです。

当時出てきた問題から大きかったものをざっと列挙してみます。
  • 当たり判定
  • カメラ
  • z-order
まず当たり判定です。
RayCast方式で当たり判定を検出する方法は知られていましたが、このゲームでは主人公と物体との当たり判定になるため、そもそも概念が違います。
さらにポリゴンがロクに出せない関係上、ペラペラの1枚同士が当たるという構成なので、自分で位置を測って独自の判定をしなければならない事になってしまいます。

次にカメラ。
Three.jsを散々調べてもカメラのスコープ範囲に関する処理が見当たりませんでした。
つまり、発生した瞬間の壁やアイテムがちらちら見えてしまう事になります。
遠ければごまかしが効くだろうと安易に考えていましたが、遠いということはそれだけ同時に表示する物体の数が増えやすい(重くなりやすい)という事です。
壁等で隠す手もありますが、それでもDOM制御が劇的に軽くなるわけではありません。
DOM制御は書き方によって劇的に軽くなるのですが、ステージ開始時にゴールまでの全ての障害物を表示するような構造はそもそもダメです。

この時のゲーム構造案はこんな感じでした。

  • 1ステージ:256マス分(非エンドレスモードの場合)
  • 障害物、アイテム配置:1マスにつき2x2の最大4個表示

エンドレスもあるため、開始時に全部出すという構造が元々不可能でした。

そして床や障害物等のz-order。
当初、画面最上位に出るべきGUI、エフェクト、そして後ろから追いかける敵は、別途作業を分けてCanvasかCSSで制御することを考えていました。
、、、と思って床とGUI等を暫定でマージしてみた処、困った問題が発生しました。
最も手前に接近した壁や床、そして障害物等が、z-order設定を突き抜けてGUI等よりも前に表示されてしまったのです。
どうやらiOSのCSS3Dで接近した物体はz-order実装にて実現していた模様です。
当然かも知れませんが、カメラの傾斜角度をちょっと変えるだけでさらにz-orderの最前面が変化してしまうため、常に最前面が同じz-order値でも無いことも解りました。



、、、となると、GUIやエフェクト等のz-orderについてどういった値にすればよいか解りません。
床の傾斜、つまりカメラの角度はゲーム性や見栄え、そして負荷にも結構な影響を与えてしまうため、この時点ではまだ厳密な角度も決まっていなかったのです。
最前面に来た出っ張っている壁はカメラの外という扱いで消してしまえばいいかとも考えたのですが、斜めになっているタイルは、どの位置で消すがが問題になります。
また、床や壁のタイルのサイズを大きくすればするほど、手前ギリギリで消すことはできなくなりますし、小さくすれば制御命令が増加するだけです。
OSや機種別の画面サイズ変化にも対応させる必要もあって、その調整も面倒くさいというレベルでは済まない程になってきました。

また、最も手前の領域はゲーム的にも結構重要で、プレイヤーが避けた後も画像が残るかどうかというのは直感性や難易度にも直結します。
具体的に言えば、画面から消えた瞬間に当たり判定もなくなるという方法がより直感的だという事になるでしょうか。
当たり前ですが、画面上にギリギリ残っている敵や弾にわざわざ近づく人はいませんし。

この最前面のド○に当たれば当然死にます。
消えれば判定も無くなったというのが自然かと。
DOM制御の重さは書き方如何で解消可能ですが、
他にも細かい問題は多々あり、時期尚早な感じは拭えないまま時間が進む日々が

この辺りから全てCSS3Dで処理する方法に限界を感じてしまい、また検証期間のタイムリミットもどんどん迫ってきていました。
(もっと良い方法でやる人は多々居るでしょうが、、、)
夢のフルCSS3Dゲームを目指していたのに、泣く泣く諦める事になってしまった訳です(泣)


しかし泣いてる暇もなく、続けて自前スペハ○のプロト実装が開始しました。
続きます。

2014年1月15日水曜日

HTML5で3Dゲー:CSS3Dプロトタイプ

今回は候補決定からThree.jsのプロト作成で速度と現実性を検討した話です。

まず具体的なゲームの画面要素はこんな感じになりました。

拙いですが、必要な要素は基本こんなもんです
ちなみにこれはUnity側で作った簡易プロト、つまりこの時点でUnityと同時進行だったので、これは置いておきますが、実はここが後々重要だったりします。
で、この上にGUIやらエフェクトやらが入る訳なんですが、この構成でThree.jsが担当しなければならない部分は以下という事に決めてしまいました。
  • 迫り来る物体(障害物、又はアイテム)
  • 無限にスクロールする床(壁)
  • 主人公とそれを追いかける敵
これらをThree.jsで、css3dRendererを使用して仮実装していきます。
まず迫り来る物体。これにモデルデータを使うかどうか検討した際、2つの現象に出くわしました。
  • 処理が凄まじく遅い
  • モデルが表示すらされない
まあ、後者は仕方ありません、スマホですし。
前者でも簡単なプリミティブなら出たのですが、複雑なデザインは絶望的でした。
しかし表示できない原因や高速化の手段を探す時間がなかったため、ここもバッサリ判断するしかありません。

  ペラペラの1枚板を物体として扱う

下位機種を考えるとこれしかありません。
となると主人公や敵もペラ1枚なのは当然ですし、見た目の差異や薄い物体の縦に対する当たり判定が問題になりますが、それは次のタイミングで考えることにしました。

次に壁と床です。
床には落とし穴などを作る案もありましたが、最初のバージョンでは単純にタイルが表示できれば良いという話になったため、2種類の案から選ぶ事になりました。
  • タイルを1枚1枚配置
  • 長いタイルを配置
こちらには当たり判定は関係なく、見た目として合っていればOKです。
また、この手のゲームにおいては、通路はゲーム中似たようなテクスチャがほぼ常に動き続けるという事が多いようなので、よくあるインスタンスの使い回しを適用することにしました。
やってる事は簡単で、以下の図のようにするだけです。


単純ではあってもメモリ節約、処理の簡略化に影響が大きく、Unityでも常にこうしないとなかなか効率化ができません。
それらを考慮し、一番最初に書いたプロト用サンプル(1枚タイルバージョン)はこんな代物でした。


画面はこんな感じで、ひたすら無限にスクロールします。
CSS3dサンプルデモの実際の動作はこちら(実際にブラウザで動きます)
画面等は一切気にせず、兎に角ひたすら床タイルがスクロールするというだけのものです。
壁があるデモバージョンもあるにはありますが、どのみちやることは一緒です。

シンプルで恐縮ですが、JavaScript側のコードはこんな感じで書きました。

// Three用変数の宣言
var camera, scene, renderer, root, arr;
// CSS3Dタイルの生成
var makeObj = function(pregress)
{
    // 画像CSSを生成
    var element = document.createElement('img');
    element.src = "http://jsrun.it/assets/l/N/z/R/lNzRT.gif";
    element.style.width = '240px';
    element.style.height = '120px';
    element.style.border = '0px';

    // CSS3オブジェクトを生成
    var object = new THREE.CSS3DObject( element );

    // 回転と位置を設定
    object.position.x = 0;
    object.position.y = 150;
    object.position.z = pregress;
    object.rotation.x = 1.57;
    object.rotation.y = 0;
    object.rotation.z = 0;
    scene.add( object );
    return object;
};
// Three.js初期化
var initThree = function()
{
    // カメラ生成
    camera = 
        new THREE.PerspectiveCamera(
                90,
                window.innerWidth / window.innerHeight,
                1,
                100);
 camera.position.set( 0, 0, 0 );
    // シーン生成
    scene = new THREE.Scene();

    // レンダラー
    renderer = new THREE.CSS3DRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.domElement.style.position = 'absolute';
 renderer.domElement.style.top = 0;
    document.body.appendChild( renderer.domElement );

    // 床の生成
    arr = [];
    for (var i = -1800; i < 0; i += 120)
    {
        arr.push(makeObj(i));
    }
};
// アニメーション処理
var animateThree = function()
{
    requestAnimationFrame( animateThree );
    renderer.render( scene, camera );
    var len = arr.length;
    for(var i = 0; i < len; i ++)
    {
        var obj = arr[i];
        obj.position.z += 6;
        if (obj.position.z >= 0)
        {
            obj.position.z = -1800;
        }
    }
};
initThree();
animateThree();

デモなのでマジックナンバーだらけですが、、(汗)
床を一定枚数生成し、それらをループで1個ずつ移動させ、指定位置に来たら遠くに戻すといった内容です。

しかし、こんなんでも確かに動きはします。
非効率な処理をしていますが、スマホでも動作は問題ありませんでした。

が、ここから検証のさらなる問題多発で、切り替えをせざるを得なくなったのですが、、、続きます。

2014年1月11日土曜日

HTML5で3Dゲーム:技術検証開始

今回は技術検証の開始話です。

さて開発が始まったのはいいものの、厳密なゲームルールも含め手探りしながら技術検証をしなければなりませんでした。
ちなみに要求されたゲームルールはテンプ○ランやエスケープ○アといった感じです。
なので上下の視点移動や弾丸、ボス戦等は不要ですが、接近する物体や床、そして当たり判定をどう再現するかが焦点となります。

あ、前回は書き忘れていましたが、3~4世代前の機種でも動かすという、別の面で厳しい話もあったのですが、最終的に飲むことにしました。
飲んだ理由としては、その某OSのCSSはWebGL非対応ですが、ハードのグラボ直結実装で速度がそこそこ早いため、ゲームが不可能とまでは言い切れなかったという点があります。

ちなみにWebGL等の対応状況に関しては以下の記事等がまとまっていて解りやすいかと。

 http://htmlgclue.blogspot.jp/2013/07/webgl20137.html


そんな状況において心の中で毎日自問自答していたのはこんな事です。

 「完全な3Dが果たしてできるのか、それともスペ○リをやるか、、、」

この2つのどっちが天国で、どっちが地獄なのやら皆目検討が付きません。
(実際にはどちらも地獄だと思いますがw)

まず、前者の道はただ一つ、CSS3Dしか頭にありませんでした。
自力でウィズのような描画を書き上げるにはとても時間がありません。
そこで簡易ラップされてて使いやすいFWを探した結果、候補を見つけました、というか現実的に1つしかありませんでした。
CSS3Dでググっていれば出てくるのでおなじみですよね。
さらに以下の記事も素晴らしく、デモの実機動作速度は特筆ものです。

 WebGL無しiOSでも簡単軽快3D。three.jsとCSS3DRendererでDOMを3D化

D&Dでスマホ上でもぐりぐり行けます。
このデモが古めの実機でぐりぐり動くのを見た時点で、完全3Dの道を選ぶならThree.jsで作るのみという結論に達しました。

そして後者の道、自前○ペハリの場合は擬似3Dになるため、これまた使いやすい2DFWを選定しなければなりません。
こちらの候補も開発者ならお馴染みの以下です。

選定の理由は、各種デモを触って、クラスリファレンスを見て、ゲームを作る際にコストが削減できそうと思ったものを独断と偏見で選んだだけなんですけどね。
上2つはまあ言わずもがなです。
pixi.jsは実機での動作速度が非常に魅力で、FW設計のシンプルさがゲーム製作時の障害になりにくそうだった点が惹かれました。

PIXI.jsのサンプルはスマホでも軽快動作してくれます。
上記の3つからどれかを使って擬似3D化するという事になります。

さて、候補選定が済んだら次はゲーム内容の制限決定です。
Untiy側が劣化に引きずられるのは仕方ないですが、そもそもHTML5版が実現できなければプロジェクト失敗です。

そのため、壁に当たったらヤバそうなゲームルールは一旦諦め、バージョンアップ時に再度挑戦という方向で進めることになりました。
例えば以下の様なものです。
  • 交差点で左右に曲がる(テンプ○ラン)
  • カーブしたり地平線が歪曲したりする
  • 開始時等の演出で、カメラ視点を大きく変更する(エスケ○プベア等)
Unityのみならどうにでもなったんですけどね、、、(遠い目)
交差点は可能性もあったのですが、時間もないのでお客様と相談し過剰な表現は勘弁させて頂きました。
こうして決定したゲーム条件はこんな感じです。
  • 視点はほぼ固定
  • 固定された通路をひたすら進む
  • ジャンプしたり取ったり避けたりする
かなりしょぼくなってしまいますが、実現のためには仕方ありません。
揃ったところで次はプロトタイプ作成で速度実験検証です。


が、続きは次回で。

2014年1月9日木曜日

HTML5で3Dゲーム

最近記事を全然書いていないので、仕事をしてきた中から脚色付きで出せるものを書いてみます。

何回かに分けますが、2013年一番大変だったHTML5で3Dゲームのお仕事の話をさせて頂きます。
まず今回は序章から。
後々実際に使った技法やコードも紹介します。(可能な範囲で)
HTML5/CSS3/Canvasでゲーム開発してる方は笑って御覧ください。



そもそも最初は、ひたすら進んでジャンプしてアイテムゲットしたりする、某タイプのスマホゲームが欲しいという打診が始まりでした。
OSは有名系2系統だったのでUnityで作ればなんてことないんですが、いきなり大変な問題が発覚。
某大手スマホ会社の有名な厳格規定の関係上、自前ストアで出すものはバイナリで作れないため、Unity版と同じものをHTML5で作り、同時リリースという事になってしまったのです。
(つまりはPhoneGapも使えず、素のHTMLやCSS、JSでどうにかするってことです)

正直最初は絶望してました。
そもそもHTML5でゲーム作るなら、Canvasで直書きする位でないと速度がでません。
DOM操作が入れば入るほど遅くなりますし、ましてや3Dって、、、。
2D系なら幾らでも転がってますが、3Dで商業系でってのは未だに見たことありません。
第一わざわざソースコード大公開でアクロバットな事したって誰も得しませんし。

まあ、売上計算はお客様なので作る側は得しない訳でもないんですが、素のHTML5ゲーがなかなか普及しないのは、簡単に盗まれやすい点もあるにはあるんじゃないでしょうかね。

また、言うまでもなく速度や互換の怖い問題もあります。
今回は有名OSのみということで、地獄のAndroid互換問題を避けられるという点は幸運でした。
しかしHTML5版はUnity版と同じゲーム性を保つというこの超難問な要求事項。
なにをどう足掻いた処で、Unity側ですらHTML5の制限その他諸々に引きずられて劣化するのは目に見えてます。

この点はお客様と何度も話し合いました。

 「某OS4は速度面でかなり絶望的になる可能性があります」
 「制限が出た場合、ゲーム性を同一にするためUnity版も劣化します」
 「派手なエフェクトは負荷を見ないと入れ込める保証はありません」

当然ながら、やるかやらないかという話にもなります。
最終的にお客様がOKを出してくれたのでゴーになりましたが、頂いた再現目標はなんと、、

 セ○マークⅢのス○ハリと同レベル

というありがたいお言葉。(真面目にありがたいです)

プライバシーの関係上、顔は伏せてありますw

確かにHTML5を取り巻くこの現状では、高い目標を掲げても実現すらしません。
私もどこまでfpsが出るか皆目検討が付きませんでした。
しかしどうにもこうにも、約3ヶ月の短い期間でダブル開発が始まってしまった訳です。

続きます。