2017.10.11
伝統的なゲームデザインをUnityで表現する
藤岡 裕吾
アカとブルー
タノシマス

ゲームエンジンの波紋

汎用ゲームエンジンというものは現在では数多あるが、その中でUnityというものは若干異質に感じる。Unityは「ゲーム開発の支援」ではなく、最初から徹頭徹尾「ゲーム開発の民主化」という掲げたコンセプトを貫いているからだ。その信念はプロとアマの壁やプラットフォームの壁だけでなく、業種間の壁にも穴を開け、それは今もなお続いている。

特筆すべきはUnityに関するコミュニティ形成、交流の場を早期から行っていたことではないだろうか。「ビデオゲーム」というスタート地点こそあれど、現在ではあらゆる業種のトレンドや技術、リソースがUnityという共通言語を通して存在する。

旧態依然とした日本の「企業のノウハウに依存するビデオゲーム」の開発は大きく揺ぎ、ソーシャルゲームの発展と共に清濁併せ呑む混乱が確かにあった。

私自身ゲームエンジンの展開によりプログラマーという職業が失われるなどと危機を抱いた時期もあったが、なんのことはない、ゲームエンジンとは開発におけるUNIX系OSのような大きな枠組みだったのだ。そしてゲームエンジンには各々の個性・設計思想が存在する。

得意なもの不得意なもの、何をもって何を目指したのか、それを理解し調理する人間が十二分に必要だった。ゲームエンジンを扱う “プログラマー” は「エンジンを作る人」ではなく、「エンジンを扱う人」というニュアンスで “エンジニア” と名前を変えていったと私個人は感じている。

今回「アカとブルー」は縦スクロール型STGというクラシカルなゲームデザインでありUnityが得意とするゲームの分野では、あまりない。そこでUnityの設計思想を汲み取り自分の中で咀嚼しつつも、あえてその意向と反して一部の実装では “エンジニア” ではなく昔ながらの “プログラマー” として向き合った。

iOS/Android用縦スクロール型シューティングゲーム 「アカとブルー」

ゲーム屋ではない技術者としての一面

弊社が「アカとブルー」において「弾雨STG」(※弊社からは基本的に “弾幕” という従来の表現を一切していない。今回その理由は割愛する。)というジャンルを選択した際に「何故Unityを選んだのか?」としばしば尋ねられる。

皆様がお察しの通り画面を埋め尽くすほどのオブジェクトを非常に安定したフレームレートで、あまつさえ固定フレーム制御を行わなければ、処理落ちを許容するクラシカルなゲームデザインの風味は出せないからだ。そこにモバイルプラットフォームという条件を追加すれば “Garbage Collection” という名の災厄を知っている誰もが顔を顰めるのは想像に難くない。

モバイル環境で1000発以上の弾が出る、というのは売り文句にもなっている。弾のバッファは敵弾用に2000発とっており、ピーク時には同一画面内に1800発以上扱う

余談だがカメラは透視射影の地上・空中と正射影の弾・UIと4つ存在している

「安定した高いパフォーマンス」という点はしばしばゲームエンジンを比較する上で語られるが、前述の通りUnityが真に目指したものはそこにはないと思っている。

だがしかし多くの面において揶揄されることは事実であり、特にモバイル環境下ではUnityは.NET Framework/C#という基盤がある関係上、確かなCPUコストを支払っている。

その根幹的な問題はIL2CPPという非常に “Rock me, baby” なアプローチをもってして対応されたが、GCへは当然我々の対応も必要になる。

逆を言えばGCという問題を解決すれば「Unityだから○○は出来ない」という言い分は多くの面で棄却できるはずだ。

「GCを完全に抑制し60FPSを安定させる」

それは多人数開発で実現するには中々に難しい。何故ならプロジェクトにアサインされたエンジニア全員がUnity/C#に対するそれなりの理解とメモリアロケートに対する神経質な対応を必要とするからだ。だからこそ今回私が一人で実装する前提となった際に、そこに今回の「技術的なウリ」を立てた。

しかしながら「技術者としての目標」は企業視点においても顧客目線においてもただのエゴでしかない。それ故に体裁を整えた理由を用意しなければ経営陣は首を縦に振ることは出来ない。

私は弊社木村にこう提案した。

「iOS/Androidのマルチプラットフォームを前提として、さらにその先の横展開を見据えるならゲームエンジンを採用するべきです。また私のキャリア的に最も扱えるゲームエンジンはUnityなのでUnityを使います。」

そして木村は経営者としてこの提案を額面通り受け取り推敲しGOサインを出した。技術者としての挑戦は基本的には技術者がわかればいい。そこに外部の理解も共感も承認欲求もありはしない、個人的で内向的で求道的な問題だ。

私のようなセンスのない人間は、ささいなことであっても己のアイデンティティ、特化分野がなければ技術者足り得ない。

基礎構築

ゲームエンジンの能力を生かすには、冒頭で述べたように設計思想を汲み取る必要がある。それは別に正解である必要はなく、作った人がどうしたかったのかを推論だてれば、ああなるほど確かにこういう設計になるだろうと納得できる。理解しようとしなければ、「なんでこんな作りに…」と不毛な苛立ちを経て無駄な独自設計を行うことになるだろう。

UnityはGameObject, Transform, MonoBehaviourという単位でのノード構成を基としてScene Viewを構築している。
ゲームエンジンを扱う上でScene Viewのようなワールド表示を見ながら構築できる恩恵は多大に受けなければ勿体ない。自前で作るのは非常に面倒だ。

カメラパスをScene View上からGUIで設定・調整している

Scene Viewによって透視射影の立体的なUIを構築しやすい
スライド時の位相による「実は奥行きがある」という騙し絵的な表現が隠しポイント

しかしながらGameObjectの数やMonoBehaviourのコールバック数が多すぎるとパフォーマンスが悪くなるという側面も併せて持つ。故にUnityの誰でも使いやすいMonoBehaviourのグローバルなコールバックは全てScene内のエントリポイントのみで扱い、他は従来ながらのトップダウン設計とし、MonoBehaviourである必要性のないクラスは継承を行わないこととした。オブジェクト構成はUnityを活用し、挙動制御はコード内で極力完結させる。

非常に雑な概念図

また今回、固定フレームは採用していない。なぜならUnityは可変フレームで設計されているからだ。ParticleSystemを多用するので全て時間駆動制御で統一したい。だがしかし固定フレームでなければ処理落ちの際の味が変わってしまう。そこで「固定時間フレーム」とした。

deltaTimeを0.016667秒で固定にすることにより時間駆動で固定フレーム挙動を表現できる。timeScaleの倍率も当然小数点レベルで反映することができる。誤差に気を使う必要があるが、それがゲームデザインに致命的な影響を与えるものでないことは、ゲームに触れればわかって頂けると思う。フレーム超過時間に関しては気を使うところは使わないと挙動がデジタル式になるので注意だ。

伝統的な味わいは伝統的な設計でこそ表現されると考える。CoroutineやSendMessageのような補助APIはご法度だ。倣う部分は倣い、倣わない部分は倣わない。このバランスが「古いけれど新しい」を実現する今回の肝だ。

データテーブル

ゲームにおいては規模が大きくなるほどデータ量も当然大きくなる。開発人数が少なければハードコーディングでもやれないことはないがいちいち細かい編集の度にコンパイルし直すのは美しくない。実行ファイルを更新することなくcsvやxml、JSONなど開発中はわかりやすいテキストフォーマットで外部に逃がすのもあるだろう。

しかしUnityで扱うのならばScriptableObjectをお勧めしたい。ScriptableObjectはUnityEditorで実行中に変更しても反映される。

通信やエンディングのイベント設定はScriptableObjectでデータを保持している。基本英語が苦手な弊社の木村も編集できるようEditor拡張で日本語化した

これにより外部ツールに頼らずUnityをゲームのオーサリング的なツールとして扱え、データ編集も同一環境で完結できる。Editor拡張でレイアウトを組むのも断然楽だ。開発のOS環境も選ばない。何よりデシリアライズ速度が文字列のパースより高速なのが個人的に非常に好ましい。ただしデータテーブルの「一部読込」は出来ないので全てオンメモリになる。その点は考慮したい。

レベルデザイン

ボスの制御はゴリゴリのコーディングだがザコ配置はインゲームで扱うツールを作成した。これもUnityを開発一元化ツールとする思想だ。

余談ではあるが背景モデルの表面検知の為にこのモードのみ実行時に動的にメッシュコライダーを貼り付け、配置時にRaycastを行い敵配置座標を計算しているUnityの標準機能を利用したツールになっている。しかしOnGUIの選択はこのような複雑なレイアウトには不向きで失敗だった。

ボスとの戦闘はカメラやアニメーションの演出を含め全てコード上での制御となるとはいえScene Viewから操作を行ってカメラ映りのいい座標を探したりする

配置データは敵設定のScriptableObjectと配置設定のシリアライズデータと、それらから必要なデータを1つにパッキングしたプレイ用のバイナリデータが存在する。

ザコの種類別設定画面設定レベルを3段階もつことで簡易的な設定から複雑な設定までサポートしている。敵配置については要件定義がなく、破壊的変更を繰り返し3ヶ月以上作り直した。後にInspector拡張ではなくEditorWindowで作るべきだったと後悔した

前述の敵設定データのIDを含む編集用配置データを保持して、実際にゲーム中に扱うバイナリデータはResources内に配置される。難易度別に吐き出す場合は1つの編集データに対して3種のバイナリデータが出力されるようになってもいるが、今回は使っていない

この辺りの設計は複雑で私自身他の作業を行っているとわからなくなる。
もちろん使っている人はそれらを意識する必要はない。今回は外法のunsafeを使用して配置情報をバイナリデータからポインタのオフセットで取り出す仕組みにしている。必要な分だけ保存するよう可変長のデータ構成にした為unsafeでポインタを使用してファイルポインタから取り出そうと考えていたが、結局データサイズが許容範囲だったので1ステージ分オンメモリで展開してしまっている。それ故にunsafeの恩恵はそれほどなく…あまり意味がなかったかもしれない。

GCへの対応

GCを伴うメモリ管理は多くの面で「想像」で行うしかない。この解答はローレベルで闘ってきたプログラマーからすれば鼻で笑われるだろう。だが、メモリの流れを「想像」することは間違いなくあなたが友人の気持ちを慮るよりずっとイージーだ。それにGCに会いたくないならゲームプレイ中のメモリのつまみ食いをやめればいい、とてもシンプルだ。

ProfilerのGC Allocが0Bで埋め尽くされるのはとても美しい。Editor上だとマウスやViewのアロケートが出てくるので最終的には端末上の計測を行う

今回AnimatorとPhysics(Collider)とシューティングシーンでのuGUIは使わないことで統一している。つまりコマアニメもモーションも当たり判定も自前で、シューティングシーンでのUIはSpriteRendererで構成されている。これらの機能は初回Active時などにメモリアロケートが発生するからだ。

コリジョンは自前で用意してScene ViewではGizmo.DrawWireで表示し、ゲーム中はデバッグメニューから確認用のスプライトを表示できるようにしている。Physicsを使った方が精密な判定となるがメインスレッドと同期しない為クラシカルな触感が再現しにくい

SpriteのコマアニメはコンポーネントにSerializeで設定することで動的なメモリアロケートを防止している

インゲームの常駐UIは全てSpriteRendererで構成される。非常に泥臭いが「レーシングカー」のようなピーキーなゲームデザインでは「乗用車」としての性能を求めたuGUIやNGUIは相性が悪い

余談ではあるが、ポーズ画面についてはuGUIを使用している。これは仕様変更やローカライズ等を含めて、説明文が最後まで確定しないからだ。メモリアロケートの排他はとにかくProfilerを多用し、あらゆる場面でアロケートの数字をゼロにする。ありがちなアロケートは文字列、delegate辺りだ。パフォーマンスに関してもGCを抑えることで副次的に大きく改善することが出来る。

GCとは異なるがテクスチャのGPUアップロードやシェーダーコンパイルのスパイクにも気をつける必要がある。初回起動時の3Dボス入場タイミングはその点において鬼門だった

終わりに

今回は伝統的なゲームデザインを現代的なゲームエンジン上で実装する為に、あえてクラシカルなコード設計をしつつもエンジンのEditorツールを有効活用することで現代的なGUIベースの開発パイプラインを構築した。

ビデオゲームは一時を境に3Dという表現へ舵を切った。今後は3Dの更なる飛躍として拡張現実へと流れるのか、3Dを利用し日本的な2Dという表現の拡張を行っていくのか、あるいはディスプレイという枠に留まるのを良しとしないのかもしれない。むしろビデオゲームはデジタルアートへと変遷していくのかもしれない。それに対して私達の世代はどう向き合っていけばよいだろうか。過去のリスペクトやオマージュであるならば、それは現代でどう表現されるべきだろうか。

「アカとブルー」で達成したかったことは「失われつつあるアタリマエ(伝統)の現代的手法による再構築」である。Unityに限らず汎用ゲームエンジンとされるものはきっと、私達が思い描いた表現に対して何らかの力を貸してくれるはずだ。

プロフィール

藤岡 裕吾

ゲームプログラマー兼Unityエンジニア。プロジェクトの基礎設計と最適化、UIアニメーションを得意とする。 ゲーム会社でコンシューマ・アーケード・iOSネイティブと渡り歩いたが、Unityと出会いフリーランスとして独立。 独自でUnityのパフォーマンスを引き出す為の設計を研究し、今回タノシマスとして『アカとブルー』のプログラム全般を担当。

アカとブルー

タノシマス
  • シューティング

プラットフォーム

  • iOS
  • Android

言語

  • 日本語
  • 英語
  • appstore
  • googleplay

GAME ゲーム

RELATED GAMES 関連ゲーム

モンキーバレルズ

グッド・フィール

“世紀末 サルカニ合戦”が幕を開ける!「サル」VS「家電」のハードで爽快なアクションシューティング!家電メーカー「カニダエレ…

BLACK BIRD

Onion Games

「BLACK BIRD(ブラックバード)」は悲しい少女の物語。独特の世界観と音楽がシンクロする、不思議の国のシューティングゲーム。あ…

Rival Megagun(ライバル・メガガン)

Spacewave Software

Rival Megagunはアーケードシューティングの激しさと対戦の盛り上がりを融合させた「対戦シューティング」です。タイト…

Earth Atlantis

Pixel Perfex

21世紀末、「大気候変動」が地球を襲った。大地の96パーセントが海に沈んだ。人類文明は堕落。機械が海洋生物に姿を変え、海は生物と機械…