Unity でゲーム開発を始める

このガイドでは、一般的なゲーム開発サイクルについて説明します。このガイドを読んだ後、リファレンスとして使用すると便利です。

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

  • 計画と設計
  • 開発とテスト
  • 公開とメンテナンス

計画と設計

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

チームメンバー全員から意見を聞く

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

  • アートチームは、キャラクターや環境のアセット テクスチャとメッシュの予算を作成する場合があります。
  • エンジニアリングは、各プラットフォームに対するプロファイリングのメモリとパフォーマンスのチェックポイントを決定する場合があります。
  • デザインは、エクスペリエンスを実現するゲーム メカニクスを計画する可能性があります。
  • オーディオの専門家は、UI、2D、3D の空間音声間の音の連続性に関する要件を確認することがあります。
  • プロダクションは、リリース要件を伝達し、チームの足並みを揃え、スケジュールどおりに進捗を管理します。

モバイル向けに設計する

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

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

モバイル向けに設計する際の固有の考慮事項について詳しくは、Unity の Android development in UnityGoogle 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 fps に制限され、30 fps に達しないと 15 fps に制限されます。

多くの Android デバイスには、60 Hz と 120 Hz のディスプレイ リフレッシュ レートが搭載されています。レンダリング レートを高くすると、サーマル スロットリングやバッテリーの消耗のリスクが高まるため、フレーム時間を大幅に短縮する(60 Hz の更新では 10 ミリ秒、120 Hz では 5 ミリ秒)メリットを慎重に検討してください。

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

Android のフレーム ペーシング ライブラリは、アプリが次のフレームを表示するのに画面のリフレッシュ レートが要求するよりも時間がかかる場合に、スムーズなレンダリングを実現します。Unity バージョン 2021 以降では、Android フレーム ペーシングを有効にすると、ディスプレイのリフレッシュ レートが目標フレームレートに最適な値に設定されます。これにより、不要なディスプレイ更新にバッテリー電力を浪費しないようにします。

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

[Project Settings] > [Player Settings] > [Optimized Fame Pacing] が表示されているダイアログ ボックス
図 1. Optimized Frame Pacing は、Unity 2019.2 以降の Player Settings で利用できます。

Vulkan API

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

Auto Graphics API

Auto Graphics API は Vulkan で使用できますが、インストールされている Unity のバージョンによって動作が異なる場合があります。このオプションは、[Project Settings](プロジェクト設定)> [Player](プレーヤー)> [Rendering](レンダリング)に移動して選択できます。

使用する 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 にフォールバックします。
[Project Settings] > [Player Settings] > [Rendering] > [Auto Graphics API]
図 2. 自動グラフィック API 設定。

手動グラフィック API

または、自動グラフィック API を無効にして、Vulkan を手動で有効にすることもできます。Unity 2021.1 以前のバージョンを使用している場合は、この方法でしか Vulkan を使用できません。

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

[Project Settings] > [Player Settings] > [Rendering] > [Graphics APIs]
図 3. 自動グラフィック API が無効になっている場合は、グラフィック API を手動で設定します。Vulkan が最初のオプションです。Unity は OpenGL ES 3.0 にフォールバックします。

描画呼び出し

画面に表示されるすべてのものは、1 つ以上のドローコールに関連付けられています。モバイル プラットフォームでは、グラフィック プロセッシング ユニット(GPU)に送信するドローコールの数を最適化して減らす必要があります。

ドローコールは、信号待ちの車の列に似ています。信号が青に変わると、信号が変わる前に一定数の車が通過できます。ライトが黄色に変わると、理想的なターゲット フレーム時間(21 ミリ秒)に達したことを示し、ライトが赤色に変わると、33 ミリ秒のフレーム時間制限に達したことを示します。これを超えると次のレンダリング フレームに影響するため、結果として得られるフレームレートは目標の 30 fps よりも低くなります。

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

シャドウ キャスティングのドローコールは、最も GPU を集中的に使用する可能性があり、シンプルな環境でも GPU 時間の大部分を消費します。シャドウ キャスティングのドローコールのコストを削減するには、ソフト シャドウの代わりにハード シャドウを使用することを試してください。ローエンド デバイスで GPU のコストがまだ高すぎる場合は、ハードシャドウの代わりにブロブシャドウの使用を検討してください。

テクスチャ

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

プラットフォームごとにサポートされている形式の一覧については、Unity ドキュメントのマニュアル: プラットフォームごとの推奨、デフォルト、サポートされているテクスチャ形式をご覧ください。

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

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

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

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

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

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

[Project Settings] > [Player Settings] > [Optimized Frame Pacing]
図 5. Device Simulator はエディタ内でのデバイスの変更をサポートしているため、デザイン上の問題を早期に発見できます。
[Project Settings] > [Player Settings] > [Optimized Fame Pacing]
図 6. デバイス シミュレータ パッケージをダウンロードする前に、[Enable Pre-release Packages] をオンにします。

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

物理学

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

  • 目標フレームレートを考慮して、固定タイムステップを適切に設定します。デフォルトは 0.02 ミリ秒または 50 Hz に設定されています。30fps のターゲットでは、0.03 以上に増やすことができます。
  • 特定のレイヤタイプのゲーム オブジェクト間のインタラクションを判断するために、メッシュ コライダーを簡素化し、レイヤ衝突マトリックスを最小化することを検討してください。

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

プロフィール

アプリ開発者は、アプリケーションが重大な障害点に達するまで、プロファイリングを無視したり、見過ごしたりすることがよくあります。プロセスに専用のプロファイリング時間をスケジュールし、次のベスト プラクティスを使用することをおすすめします。

  • プロファイリング時間をランダムに割り当てるのではなく、開発中に割り当てられる重要なポイントを特定します。
  • プロファイル スナップショットを保存して、Unity Profile Analyzer で使用します。
  • ターゲット デバイスでゲームをプロファイリングして、開発の現在の段階でゲームがどのように動作するかを正確に把握します。
  • ゲームのさまざまな部分をプロファイリングします。
  • プレーヤーがどのようにゲームをプレイしているかを把握します。(アイドル状態や一時停止画面でのみゲームをプロファイリングしないでください)。
  • ゲームをしばらく実行した後の持続モードのプロファイル。モバイル デバイスが熱いときに発生する可能性のあるスロットリングの問題を見つけるのに役立ちます。

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

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

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

Unity でのゲームのプロファイリングについて詳しくは、Unity の動画「Introduction to profiling in Unity」または「Ultimate guide to profiling Unity games」をご覧ください。

メモリ管理

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

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

文字列のインプレース連結(「this」+「is」+「a」+「bad」+「idea」と StringBuilder.Concat() 関数呼び出しなど)よりも、文字列操作の大きなシーケンスには StringBuilder クラスの使用を検討してください。

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

優先 ScriptableObject 型に対して TextAsset と JSON テキスト リソースを評価します。ScriptableObjects は、シーン間のデータ保存を効率的に処理し、エディタから再生時間への変更を可能にします。

モバイル最適化にデフォルトの JSON ハンドルの代替を使用する方法については、Hutch の記事 The hidden optimization in network games をご覧ください。

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 のドキュメントのイベント関数の実行順序をご覧ください。メモリ管理の詳細については、コース Memory Management in Unity をご覧ください。

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

プレハブ プーリング

CPU フレーム時間の急増は、ゲームプレイ中のプレハブのインスタンス化が原因であることがほとんどです。ゲームプレイに入る前に、発射物、スポーン可能な敵、視覚効果のオブジェクト プールをプリウォームすることを検討して、起動時の CPU スパイクを軽減または解消します。シーンの読み込み中や導入シーケンス中に、追加の最適化を複数の「初期化フレーム」に分散できます。

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

アセット配信

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

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

Addressables

Addressables の命名システムを準備して確認しておけば、実行時に動的リソース(プレハブ、テクスチャ、サウンド ファイルなど)を設定する操作は複雑ではなくなります。アドレス指定可能なアセットは、コンテンツの配置方法とコンテンツのビルドおよび読み込み方法を分離します。Addressables システムは、Resources フォルダとアセットバンドルを置き換えて、アセットの参照と実行時の読み込みを簡素化します。

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

アドレス指定可能なアセット レイアウトでは、共通バンドルにバンドルするアセットが少なすぎたり多すぎたりすると、メリットとデメリットがあります。Addressables を使用したコンテンツ管理の詳細については、Addressables を使用してコンテンツ管理を簡素化するをご覧ください。

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

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

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

Unity Open Project: Chop Chop のソースコードは GitHub で入手できます。このプロジェクトは開発が終了しましたが、git リポジトリとドキュメントは引き続き利用できます。

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

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

すべてのリソース フォルダをすばやく見つけるには、[プロジェクト] パネルで「Resources」を検索します。各アイテムを選択して、その内容とゲームに必要なアイテムかどうかを確認できます。

図 7. Unity アセットストアからダウンロードしたフォルダには、複数の Resources フォルダが潜んでいる可能性があります。これらをクリーンアップして、アプリケーション バンドルにパッケージ化されないようにします。

公開とメンテナンス

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

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

対象ユーザーを限定してリリースし、大規模なベータテストを実施することも、すべての市場でゲームを完全に利用可能にすることもできます。限定リリースでは、より多くのライブ オーディエンスとデバイスのコレクションに基づいて、アプリケーションのパフォーマンスを調整できます。

たとえば、Android Performance Tuner for UnityGoogle Analytics for Unity を使用して、アプリのパフォーマンスとプレーヤーの傾向に関する分析情報を取得できます。この分析情報に基づいて、開発チームはアップデートを調整してプッシュできます。また、アナリティクス データを使用して、同じジャンルの続編や関連ゲームを計画することもできます。

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

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

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

モニタリングとトラッキング

ゲームのライブオペレーションと配信のフェーズでは、Android Vitals を使用して、開発やテストの段階ではアクセスできなかったデバイスのパフォーマンスの問題を追跡できます。詳しくは、リーチとデバイス、Android Vitals のゲーム向け新機能をご覧ください。

大規模な開発チームでは、デバイスのパフォーマンスに関連する指標を提供する独自のカスタム ゲーム テレメトリー パイプラインが用意されていることがよくあります。Android Performance Tuner(APT)と対応する Unity プラグインを活用して、フレームレート、グラフィックの再現性、読み込み時間、読み込みの放棄に関連する指標を調整してください。Android Performance Tuner を Unity ゲームに統合するの手順ガイドに沿って操作します。

ゲームのライフサイクルは、公開後も終わりません。パフォーマンスとフィードバックをモニタリングし、維持し、対応することは、ユーザーの満足度を高め、好意的なレビューを獲得し、最終的にすべての市場でゲームの導入を促進するうえで非常に重要です。