Unity でゲーム開発を始める

このガイドでは、一般的なゲーム開発サイクルについて概説します。このガイドをお読みいただいた後、リファレンスとしてご活用ください。

Unity の場合、開発ライフサイクルは次の 3 つのフェーズで構成されます。

  • 計画と設計
  • 開発とテスト
  • 公開と維持

計画と設計

計画と設計のフェーズでは、ゲームの構築方法を決定します。また、モバイル用の開発における課題への対処方法を決定し、開発で使用するツールとプロセスを特定します。

チームメンバー全員から意見を聞きましょう

アート、エンジニアリング、デザイン、オーディオ、プロダクションの各チームと協力して、実装タスクを特定し、記録します。次に例を示します。

  • アートチームは、キャラクターや環境向けのアセット テクスチャやメッシュ バジェットを作成できます。
  • エンジニアリング チームは、各プラットフォームに対してプロファイリングするためのメモリとパフォーマンスのチェックポイントを決定する場合があります。
  • 設計では、エクスペリエンスを可能にするゲーム メカニクスが計画される場合があります。
  • UI、2D、3D 空間サウンド間の音声の連続性に関する要件は、オーディオの専門家によって確認される場合があります。
  • 本番環境はリリース要件を伝え、チームの連携を維持して軌道に乗せることがあります。

モバイル向けにデザインする

モバイル プラットフォーム向けのアプリ開発では、次のような固有の考慮事項があります。

  • 画面アスペクト比の変更
  • 消費電力
  • サーマル スロットリングとプロセッサ スロットリング
  • タップ入力
  • クロス プラットフォーム開発
  • グラフィック API(Vulkan または OpenGL ES)

モバイル用に設計する際の考慮事項について詳しくは、Unity の Unity での Android 開発Google Play アカデミーをご覧ください。

開発とテスト

開発とテストのフェーズでは、ゲームをビルドし、テストとリリース前の準備を行います。リリース要件を満たす準備として、Google Play で限定的な内部テストを実施します。Play Asset Delivery と Unity Addressables システムに基づいて、Unity でデプロイ戦略を改善し、アセットを整理します。

以下のセクションでは、Android 向けの開発に役立つ Unity のツールと手法について説明します。

レンダリング

レンダリングとは、画面上の Unity シーンから 3D アセットと 2D アセットを描画するプロセスです。Unity エンジンがレンダリングを処理しますが、Android プラットフォームに関するいくつかの要素を考慮することが重要です。

テクスチャ

最大のテクスチャ サイズが必要かどうかは、ターゲット デバイスに基づいて判断します。メモリ割り当てをプロファイリングする場合は、ターゲット テクスチャ サイズの変更で削減できる可能性がある費用を確認します。

フレーム時間

Android デバイスでの過熱を防ぐには、フレーム時間の値を平均 21 ミリ秒未満にすることを目標にしてください。読み込み中や短い映画のようなエクスペリエンスなど、フレーム時間が 21 ミリ秒を超えることがありますが、コアゲーム エクスペリエンスの 21 ミリ秒のしきい値を超えないようにする必要があります。

モバイル プラットフォームでは、最小目標に達しない場合、強制 VSync によってフレームレートが調整されます。たとえば、60 Hz の画面アップデートでは、60 fps に達しない場合、ゲームは 30 にスロットリングされ、30 に達しない場合は 15 にスロットリングされます。

多くの Android デバイスは、60 Hz と 120 Hz のディスプレイのリフレッシュ レートを搭載しています。レンダリング レートを上げるためにサーマル スロットリングやバッテリーの消耗のリスクを負うことなく、はるかに短いフレーム時間(60 Hz のアップデートの場合は 10 ミリ秒を目標、120 Hz の場合は 5 ミリ秒を目標)をターゲットにする利点を比較検討してください。

Unity でゲームに特定のフレームレートを設定するには、Application.targetFrameRate を使用します。

Android の Frame Pacing ライブラリを使用すると、アプリが画面のリフレッシュ レートよりも次のフレームの表示に要する時間が長くなった場合に、スムーズにレンダリングできます。Unity バージョン 2021 以降の場合は、Android フレーム ペーシングを有効にすると、ディスプレイのリフレッシュ レートがターゲット フレームレートに最適な値に設定されます。これにより、ディスプレイを不必要に更新しても、ゲームはバッテリーを浪費しません。

ライブラリを有効にするには、[Project Settings] > [Player] の [Settings for Android] で、[Optimized Frame Pacing] チェックボックスをオンにします。

[プロジェクト設定] > [プレーヤー設定] > [最適化されたフェイム ペース] を表示するダイアログ ボックス
図 1. [Optimized Frame Pacing] は、Unity 2019.2 以降では [Player Settings] で使用できます。

Vulkan API

Vulkan は、クロス プラットフォームで高性能な 3D グラフィック API であり、OpenGL ES と比較してオーバーヘッドが低くなります。Unity では 2 つの方法で Vulkan を使用できます。

Auto Graphics API

Vulkan で Auto Graphics API を使用できますが、これは、インストールした Unity のバージョンに応じて異なる動作になります。これを行うには、[プロジェクト設定] > [プレーヤー] > [レンダリング] に移動します。

使用する Unity のバージョンを選択する際は、次の点に注意してください。

  • Unity 2021.1 以前のバージョンは、Auto Graphics API で Vulkan をサポートしていません。Unity が OpenGL ES 3.2 を使用しようとしている。デバイスが OpenGL ES 3.2 をサポートしていない場合、Unity は OpenGL ES 3.1、3.0、2.0 の順番にフォールバックします。
  • Unity 2021.2 以降のバージョンでは、最初に Vulkan を使用します。デバイスが Vulkan をサポートしていない場合、Unity は OpenGL ES 3.2、3.1、3.0、2.0 にフォールバックします。
[プロジェクト設定] > [プレーヤー設定] > [レンダリング] > [Auto Graphics API]
図 2. Auto Graphics API の設定

手動グラフィック API

また、Auto Graphics API を無効にして、Vulkan を手動で有効にすることもできます。Unity 2021.1 以前のバージョンを使用している場合は、これが Vulkan を使用する唯一の方法です。

Vulkan がこのリストで OpenGL ES よりも上位である場合、Unity は最初に Vulkan の使用を試みます。デバイスが Vulkan をサポートしていない場合、Unity は OpenGL ES で実行されます。最新のグラフィック API の使用方法やゲームのパフォーマンスの最適化方法など、Android での Vulkan の詳細については、Vulkan のスタートガイドをご覧ください。

[プロジェクト設定] > [プレーヤー設定] > [レンダリング] > [グラフィック API]
図 3. Auto Graphics API が無効になっている場合に、グラフィック API を手動で設定します。Vulkan が最初のオプションです。Unity は OpenGL ES 3.0 にフォールバックします。

描画呼び出し

画面に表示されるすべてのものが、1 つ以上の描画呼び出しに関連付けられています。モバイル プラットフォームでは、GPU に送信する描画呼び出しの数を最適化して減らす必要があります。

ドローコールは、信号機に並ぶ車にたとえて考えてください。ライトが緑色に変わったら、ライトが変化する前に一定数の車が通過できます。ライトが黄色に変わると、理想的な目標フレーム時間(21 ミリ秒)に達し、ライトが赤色に変わると、33 ミリ秒のフレーム時間上限に達します。それを超えて次のレンダリング フレームに影響を与えるため、結果のフレームレートは目標の 30 fps より低くなります。

ゲームのドローコールのパフォーマンスを改善する方法については、Unity サポートのバッチ処理の記事をご覧ください。

シャドウ キャスティングの描画呼び出しは最も GPU を消費し、シンプルな環境であってもほとんどの GPU 時間を消費する可能性があります。シャドウ キャストの描画呼び出しのコストを削減するには、ソフト シャドウの代わりにハード シャドウを使用してみます。それでもローエンド デバイスで GPU のコストが高すぎる場合は、ハード シャドウではなく、blob シャドウの使用を検討してください。

テクスチャ

Android で RGB テクスチャと RGBA テクスチャに推奨されるテクスチャ圧縮形式は ASTC です。Unity では、Android で使用する最小のテクスチャ圧縮オプションは ETC2 です。[Unity のビルド設定] で、ASTC のバックアップとして ETC2 にフォールバックできます。

プラットフォーム別のサポートされている形式の一覧については、Unity のドキュメントの Manual: Recommended, default, and supported text format, by platformをご覧ください。

ユーザー インターフェースとアスペクト比

Unity デバイス シミュレータ ツールを使用すると、さまざまなデバイスの画面の解像度、向き、アスペクト比を Unity Editor で直接プレビューできます。[ゲーム] ビューと [Device Simulator] ビューを切り替えることができます。

このツールのプレビューについては、Unity でデバイス シミュレータを使用してゲームをシミュレートするをご覧ください。

図 4. Trivial Kart を実行しているデバイス シミュレータ。

Trivial Kart のソースコードは GitHub の games-samples リポジトリにあります。

プルダウン メニューでデバイス オプションを選択すると、Device Simulator ビューで UI キャンバス要素のレイアウトと正確性をすばやく確認できます。

[プロジェクト設定] > [プレーヤー設定] > [フレーム ペーシングの最適化]
図 5. Device Simulator はエディタ内でのデバイスの変更をサポートしているため、設計上の問題を早期に発見できます。
[プロジェクト設定] > [プレーヤー設定] > [名声のペースの最適化]
図 6.Device Simulator パッケージをダウンロードする前に、[Enable Pre-release Packages] をオンにします。

Unity のその他の UI 最適化手法については、Unity のチュートリアルの Unity UI の最適化をご覧ください。

物理学

Unity には Nvidia PhysX エンジンが組み込まれています。デフォルトの設定はモバイルで高コストになることがあるため、次の点に注意してください。

  • 目標フレームレートを検討し、それに応じて固定時間ステップを設定します。デフォルトは 0.02ms または 50Hz です。30 fps の目標では、0.03 以上に増やすことができます。
  • 特定のレイヤタイプのゲーム オブジェクト間のインタラクションを決定するために、メッシュ コライダーを簡素化し、レイヤ衝突行列を最小限に抑えることを検討してください。

モバイルゲームの物理設定と最適化については、Unity の Optimize Your Mobile Games eBook をご覧ください。

プロファイル

アプリ デベロッパーは、アプリケーションが重大な障害点に達するまでプロファイリングを見落とす、または無視することがよくあります。プロセスに専用のプロファイリング時間を確保し、次のベスト プラクティスに従うことをおすすめします。

  • プロファイリング時間をランダムではなく、割り当て可能な重要なポイントを開発中に特定します。
  • Unity プロファイル アナライザで使用するプロファイルのスナップショットを保存します。
  • ターゲット デバイスでゲームのプロファイリングを行い、現段階での開発段階におけるゲームのパフォーマンスを正確に把握します。
  • ゲームのさまざまな部分をプロファイリングする。
  • プレーヤーのゲームのプレイ方法をプロファイリングします。(アイドル状態や一時停止画面のときのみゲームのプロファイリングを行わないでください)。
  • ゲームをしばらく実行した後、維持モードでプロファイルを作成することで、モバイル デバイスが熱くなったときに発生する可能性があるスロットリングの問題を検出できます。

次のプロファイリング ツールを個別に、または組み合わせて使用できます。

  • Unity Profiler は、Unity Editor でコードに対して実行でき、開発モードのビルドを実行しているスタンドアロンの Android デバイスに接続できる、完全統合型のパフォーマンス分析ツールです。

  • Android GPU Inspector: Android GPU Inspector(AGI)を使用すると、フレームレベルのデバッグを行うことができます。また、AGI は GPU、CPU、メモリ、バッテリー、GPU カウンタなどのシステム サービスの分析も行います。

Unity でゲームのプロファイリングを行う方法について詳しくは、Unity でのプロファイリングの概要の動画、または Unity の Unity ゲームのプロファイリングに関する究極のガイドをご覧ください。

メモリ管理

Android プロセスは、ターゲット デバイスで使用可能なメモリを共有します。ターゲット テストデバイスに十分なメモリリソースがある場合は、メモリ使用量をプロファイリングする必要があります。セッションとメモリ使用量の傾向を適切に比較できるように、ゲーム内の一貫したポイントでメモリテストを実行します。

C# で記述されたスクリプトで作業する場合は、文字列の使用、文字列の比較、文字列関連オブジェクト(ゲーム設定の JSON ファイルなど)の割り当てに注意してください。これらは頻繁にメモリ割り当てを生成し、断片化の原因になる可能性があります。

大規模な一連の文字列操作には、StringBuilder.Concat() 関数呼び出しではなく、"this" + "is" + "a" + "bad" + "idea" などの文字列のインプレース連結ではなく、StringBuilder クラスの使用を検討してください。

文字列の詳細については、Unity ドキュメントの文字列とテキストをご覧ください。

TextAsset と JSON テキスト リソースを優先の ScriptableObject タイプと比較して評価します。ScriptableObjects は、クロスシーンのデータ ストレージを効率的に処理し、エディタからプレイまでの時間の変更を可能にします。

デフォルトの JSON ハンドルに代わるモバイル最適化の使用については、Hutch のネットワーク ゲームに隠れた最適化に関する記事をご覧ください。

Memory Advice API を使用して、実行時のメモリ使用量を確認します。API は、メモリ使用量が高、通常、低くなるようにインジケーターを表示します。インジケーターをサブスクライブして最新情報を入手することも、直接ポーリングして現在のステータスを確認することもできます。不適合な兆候が表示されたら、ゲーム オブジェクト プールまたはキャッシュを減らすことを検討してください。ライブ オペレーション中にこのコンテキストをゲームのテレメトリーに含め、リリース後にパフォーマンス指標を確認します。

Android デバイスでのメモリ構成と、Unity が連携する仕組みの詳細については、Android のメモリ使用量について(Google I/O '18 より)をご覧ください。この動画では、メモリの問題の種類と、どのような場合にローメモリ キラーが発生するかについて説明します。

ガベージ コレクション

マネージド メモリ環境のガベージ コレクションは、アプリケーションでリサイクルできる未使用のメモリ フラグメントをクリーンアップします。メモリリソースの不要な割り当てを避けるため、ガベージ コレクションのベスト プラクティスに従ってください。

たとえば、オンデマンド割り当て(GameObject.Instantiate)を使用するのではなく、ゲーム オブジェクト プールを作成します。大規模なプールの場合は、エントリレベルの Android デバイスでゲームが応答しなくなるリスクを軽減するために、複数のフレームを割り当てることを検討してください。

MonoBehaviour の先頭から呼び出される単純なコルーチンについて、次のコード スニペットを考えてみます。

// Option 1: Bad for memory management - causes allocation each iteration
IEnumerator UpdateEnemyTarget() {
  while (enabled) {
    yield return new WaitForSeconds(1.0f);
    // Some intermittent function check
  }
}

// Option 2: Better for memory management - allocation of yield instruction once, reused each iteration
private YieldInstruction waitForSecond = new WaitForSeconds(1.0f);
IEnumerator BetterUpdateEnemyTarget() {
  while (enabled) {
    yield return waitForSecond;
    // Some other intermittent function
  }
}

MonoBehaviour テンプレート ファイルを編集すると、デフォルトの Start() および Update() スタブ関数を削除できます。これにより、開発時に誤って空の関数が残らなくなります。

MonoBehaviour イベントの実行順序の概要については、Unity ドキュメントのイベント関数の実行順序をご覧ください。メモリ管理の詳細については、Unity でのメモリ管理コースをご覧ください。

モバイルゲームのパフォーマンスを最適化するヒントについては、モバイルゲームのパフォーマンスを最適化する: Unity のトップ エンジニアによるプロファイリング、メモリ、コード アーキテクチャのヒントをご覧ください。

プレハブ プーリング

CPU フレーム時間の急増のほとんどは、ゲームプレイ中の Prefab のインスタンス化によって発生します。ゲームプレイに入る前に、発射体、生成可能な敵、視覚効果のオブジェクト プールをプレウォーミングすることで、起動時の CPU の急増を低減または排除することを検討してください。シーンでの読み込みシーケンスまたは導入シーケンス中に、複数の「初期化フレーム」に追加の最適化を分散できます。

Unity Asset Store には、ゲーム オブジェクト プーリング管理に関連するサードパーティのプーリング アセットが多数あります。独自のインタラクションを作成することもできます。Unity Learn でのオブジェクト プールの概要をご覧ください。

アセット送付

アプリを Google Play に初めてデプロイしたときのサイズには制限があります。ゲームのサイズと性質によっては、目的のエクスペリエンスをプレーヤーに提供するために、ゲームリソース(キャラクターモデル、環境、UI 要素など)の一部またはすべてが必要になる場合があります。

Play Asset Delivery(PAD)サービスを使用して、インストール時、ファスト フォロー時、またはオンデマンドでゲームが必要とするアセットを管理できます。Unity Asset Bundle は、PAD をサポートするように統合されており、このツールを使用して配信する要素を指定できます。

アドレス指定可能

Addressables の命名システムを用意して見直すことで、プレハブ、テクスチャ、サウンド ファイルなどの動的リソースを実行時にセットアップするのに手間が省けます。アドレス指定可能なアセットは、コンテンツの配置方法と、コンテンツの作成や読み込み方法を切り離します。Addressables システムにより、Resources フォルダと Asset Bundle が置き換えられ、アセットの参照と実行時に読み込む方法が簡略化されます。

例については、GitHub の Addressables パッケージを使用したデモ プロジェクトをご覧ください。Addressables の開発について詳しくは、Unity ブログの Addressable Asset System をご覧ください。

Addressable Asset Layout を使用する場合、共通のバンドルにバンドルするアセットが少なすぎる、または多すぎる場合、長所と短所があります。Addressables によるコンテンツ管理の詳細については、Addressables でコンテンツ管理を簡素化するをご覧ください。

Addressables システムに慣れるため、スタンドアロンのデモを設定してアクセスモードを試すことができます。オープンソース プロジェクトの BuildLayout Explorer for Unity 2019.3 以降を表示し、Addressables によって生成された buildlayout.txt レポートを調べることもできます。

Unity Open Project である Chop Chop のアセットは、すべての読み込みと読み込み解除に Addressables システムを使用してパッケージ化されました。Addressables バンドルの構成と設定のチュートリアルについては、Addressable Assets(Addressable アセット)を使用したコンテンツのパッケージング | Open Projects Devlog をご覧ください。

Chop Chop プロジェクトでは、デフォルトで読み込まれる唯一のシーン(初期化シーン)が、プロジェクト内のアセットへの直接リンクではなく AssetReferences を使用するように構成されました(シーン、プレハブなど)。

Unity Open Project: Chop Chop のソースコードは GitHub で入手できます。このプロジェクトは開発されていませんが、Git リポジトリとドキュメントは引き続き利用できます。

サードパーティ プラグイン

Unity Asset Store のプラグインなどのサードパーティ プラグインを使用する場合は、フォルダを確認し、Resources フォルダから不要なアセットを削除してください。Unity はビルドプロセス中に、Resources フォルダに含まれるすべてのアセットを収集し、ランタイムにアクセス可能な単一のバンドルにパッケージ化します。これは最終的なパッケージに肥大化を引き起こす可能性があり、多くの場合は必要ありません。

すべてのリソース フォルダをすばやく見つけるには、[Project] パネルで [Resources] を検索します。各コンポーネントを選択して、そのコンポーネントが何であるか、ゲームに必要かどうかを判断できます。

図 7. Unity Asset Store からダウンロードしたフォルダ内に、複数の Resources フォルダが存在する場合があります。これらをクリーンアップして、アプリケーション バンドルにパッケージ化されないようにします。

公開と維持

モバイルゲームをリリースする準備ができたら、リリース先、アルファ版テストとベータ版テストの方法、リリース後にパフォーマンスをモニタリングして追跡する方法を決定します。

限定リリースからのフィードバックを分析する

ターゲット ユーザーを限定してリリースし、大規模なベータ版テストを実施できます。また、すべての市場で完全にリリースできるようにゲームを有効にすることもできます。限定リリースでは、幅広いライブ オーディエンスとデバイスのコレクションに基づいてアプリのパフォーマンスを調整できます。

たとえば、Unity 向け Android Performance TunerUnity 向け Google アナリティクスを使用して、アプリケーションのパフォーマンスとプレーヤーの傾向に関する分析情報を得ることで、開発チームはこれらを調整してアップデートをプッシュできます。また、分析データを使用して、似たジャンルの続編や関連ゲームの計画を立てることもできます。

アルファ版テストとベータ版テスト

Google Play Console でアプリ プロファイルを設定したら、アルファ版とベータ版の公開テストビルドを準備し、リリース前審査のために一部のユーザーに配布できます。対象を限定することで、大規模なデバイスプールで最終的な問題を解決し、グローバル リリースの公開前に最初のフィードバックを収集して対応できます。

Unity ビルドが Android App Bundle を通じて配布される。詳しくは、Unity のマニュアル: Google Play への配信をご覧ください。APK ファイルから AAB 形式への変更についても説明しています。

モニタリングと追跡

ゲームの LiveOps と配信のフェーズでは、Android Vitals を使用して、開発やテスト中にアクセスすることができなかったデバイスのパフォーマンスの問題を追跡できます。詳しくは、「リーチとデバイス」と Android Vitals におけるゲームの最新情報をご覧ください。

多くの場合、大規模な開発チームには、デバイスのパフォーマンスに関連する指標を提供する独自のカスタム ゲーム テレメトリー パイプラインがあります。Android Performance Tuner(APT)と対応する Unity プラグインを利用し、フレームレート、グラフィック忠実度、読み込み時間、読み込みの放棄に関連する指標をダイヤルインしてください。Android Performance Tuner を Unity ゲームに統合するの手順ガイドをご覧ください。

公開後もゲームのライフサイクルは継続します。パフォーマンスとフィードバックのモニタリング、維持、対応は、ユーザーの満足度を高め、好意的なレビューを行い、すべての市場で最終的にゲームを導入するために不可欠です。