Yahoo!ニュース

IDでもっと便利に新規取得

ログイン

『ドラクエウォーク』が目指した、“位置ゲー”ならではの負荷低減と最適化

配信

  • この記事についてツイート
  • この記事についてシェア
リアルサウンド

 今年はコロナ禍の影響からオンライン開催となった『CEDEC 2020』。本稿では各セッションから「ドラゴンクエストウォークにおける Maps SDK for Unity とECS利用事例」の模様を記す。 【写真】『ドラクエウォーク』が目指すものを示した講演資料  登壇者はコロプラの西尾昌哲(エンターテインメント本部エンジニア)。Unity2018ではPreview機能であったECS(Entity Component System)を利用し、パフォーマンスの改善を計った取り組みとその結果について語られた。 ■SDKでマップを自動生成 『ドラクエ』風にカスタマイズ  『ドラゴンクエストウォーク』は“位置ゲー”(位置情報を利用したゲーム)として開発。マップデータはGoogle Maps Platform Gaming Solutionから取得して表示している(他のゲームでは『ウォーキング・デッド』『妖怪ウォッチワールド』『モンスターストライク』などでも採用)。  ゲームの開発はMaps SDK for Unityにて、このGoogle Maps Platform Gaming Solutionを読み込んで利用している。簡単なコードでUnity上にマップが生成されるのが特徴で、例としては、緯度・経度など、いくつかのパラメーターを指定。地図データをダウンロードして、各種マップ要素のメッシュが設定されたGame Objectの生成まで行ってくれる。  マップを生成するために必要最低限のコードは、まずSDK(Software Development Kit)から提供されているMaps Service Componentを取得して、ワールド限定に当たる緯度・経度を設定。そしてロードマップメソッドで範囲とオプションを指定すると、自動的にシーンにマップが生成されていく。ただ、そのまま使用するわけではなく、実世界の雰囲気を残しつつ『ドラクエ』の世界観を表現していくことになる。  マップを生成・描画する際に最適化も行う。フィールドには高さのあるオブジェクトがいくつかあるが、キャラクターのめり込みを回避する当たり判定をとっていない。フィールドに半透明のスプライトで多く表示される「回復スポット」は、これらのオブジェクトのマテリアルが分かれていると、交互に配置された時にDynamic Batchingが効かなくなるため、できるだけDynamic Batchingが効くようにテクスチャーをまとめて同じマテリアルで使用している。  石や草や花などのオブジェクトも、それぞれに板影がついているが、それらもDynamic Batchingを阻害していたため、Render Queueを変えて他の半透明オブジェクトよりも先にまとめて描画している(足跡についても同様)。モバイルでは重いと言われるCut Offも、描画をまとめるためにところどころで使用。例えば木や地名の文字などで、この対応を入れた時にパフォーマンスのチェックもしてみたところ、顕著な低下は見られなかった。  先述のような感じで複数のテクスチャーを使い、道と地面をまとめて合成しているが、ピクセル処理がかなりの負荷になった。そこでできるだけ描画面積を減らして、ピクセル処理の負荷が下がるようにRender Queueも調整。不透明でピクセル負荷も低い建物の跡や森の領域などを先に描画して、その後にピクセル負荷の高い地面を描画するようにした。雲の影については、各種の地形シェーダーで雲のテクスチャ―をブレンドしているだけなので負荷は軽い。  キャラクターとUIを除いたフィールドのDraw Call数は、場所や状況にもよるが40~50くらい。恵比寿周辺だと道や押し出した建物などは数千ほど生成されるが、それらのメッシュをある程度の範囲で結合している。 ■ETSのメリット・デメリット 頻繁なアップデートに注意  ECSを利用して気づいた利点として、Entityの生成・破棄が高速というのは良かった。やはりGame Object実装の時は生成・破棄の処理が重いようで、カメラに映らなくなった領域の木は非アクティブにしてオブジェクトプールに保存、再びカメラに映る時にプールから取り出して再利用するようにしていた。ところがカメラを回転させた時に、たまにカクカクと引っかかる時があった。Entity実装に変えてからは、普通に破棄しても引っかかることがなくなったため、かなり改善したようだ。  ビルボード実装自体は、かなりシンプルになったと思う。Entity実装だと、Entityの生成・破棄とビルボード処理が分離されているので、かなり取り回しが楽になった。Game Object実装の場合は、ビルボード生成時に、そのトランスフォームをまとめて管理するコンポーネントに渡さないといけなかったりで地味に面倒だった。ECS(DOTS)はパフォーマンスに期待されがちだが、ものによっては実装がシンプルになるのも良い点。Render Meshの更新も簡単にできたのが良かった。  このゲームはイベント中にフィールドの見た目をガラッと変える場合もあり、Render Mesh内部のメッシュやマテリアルを更新するだけで実現できた。Game Objectで実装する場合のMesh FilterのShered Mesh、Mesh RendererのShered Matterialを更新するのと同じ感覚だった。ECSにすることで描画周りが面倒になるのではないかと思ったが、そうでもなかった。  将来的な不安要素としては、Unityやパッケージのアップデートで発生する問題を抱えることになる。Preview機能を使うということは、頻繁なアップデートが予測されるので、パッケージのアップデートが終わる頃には大幅な変更になっている可能性が高い。またアップデートした後もまだPreview機能だったりすると、Unityや他のパッケージとの組み合わせでも問題が発生するかもしれない。  あまりないと思うが、ストアの規約が変更されて、それに抵触してしまうかもしれない。考えたらキリがなく、大きな問題が起こったら、作り直すくらいの気持ちでいた方がいいだろう。そのためPreview機能を使う場合は、ゲーム本体から切り離せるくらいの部分に留めておくのが良さそうだ。  最後に、モバイルでも使えたのはありがたかった。特に古い機種でも動くので、CPUの負荷やメモリ使用量の削減やバッテリー消費の削減にも、より効果が出たと思う。今回、静的オブジェクトとビルボードでしか使っていないが、物量が多いシミュレーションとかでも十分に使えそうだと感じた。クラッシュなどの不具合も、想像していたより全然発生しなかったものの、Game ObjectでやっていたようなUnityのエディター機能は使えないため、チーム開発には不向きだと思った(これは将来的には改善される予定らしい)。

真狩祐志

【関連記事】