Unity Pro Tips

DEVELOPER詳細

Unity を使用したコンソールビデオゲームの開発に関するヒント

<このページで学べる内容>

PlayStation、Microsoft Xbox One、Nintendo Switch 用のゲームを制作するための開発環境をセットアップするためのヒント。 Unity を使用して開発しているインディーチームは、現在ひときわ勢いのあるコンソールゲーム界の屋台骨ともいえる存在です。この記事を読み、開発環境をセットアップする方法、パフォーマンスをプロファイリングおよび最適化する方法、ゲームコンテンツを整理およびデバッグする方法などについて学んでいきましょう。これらのヒントは Unity の Xbox One 向け開発者である Oli Williams によって提供されたものです。

プラットフォームホルダーに登録する

コンソールゲームを開発するには、プラットフォームホルダーに開発者として登録する必要があります。Microsoft Xbox OnePlaystationNintendo Switch に登録する方法については、各リンクをクリックして確認してください。

各コンソールごとの提出要件は、登録後にすぐ確認することができます。ゲームの導入を開始する前に目を通し、制作全体にわたって心がけるようにしてください。 

プラットフォームによっては、さまざまなサービスでホワイトリストに登録されたり、ドメイン名や会社を登録したりするのに、静的 IP アドレスが必要になる場合があります。繰り返しになり、恐れ入りますが各種要件を必ず確認するようにしてください。   

Microsoft、Sony、任天堂においては、秘密保持契約に署名するには登録開発者であることが求められることに注意してください。

開発環境をセットアップする

Unity のバージョン
Unity の各バージョンは、特定のバージョンのコンソール SDK と互換性があります。コンソール SDK は、登録後にプラットフォームホルダーからダウンロードできます。プラットフォームホルダーではコンソール SDK を定期的にアップグレードしています。Unity ではそれに合わせて、最新の SDK との互換性を保持するために、現行のバージョンの Unity(LTS バージョンを含む)をすべてアップグレードしています。とはいえ、お使いの Unity のバージョンが対応する SDK のバージョンとペアリングされていることを確認することが重要です。 

登録してコンソール SDK をダウンロードしたら、お使いの現行のバージョンの Unity を使用して、コンソールゲームの開発を開始できます。ただし、提出の準備をするときは、関連する LTS ブランチに移行することを強くお勧めします。これが最も安定したバージョンであり、重要なバグ修正や SDK のアップグレードが含まれているからです。 

その他のハードウェア要件
Visual Studio がインストールされた Windows 10 PC が必要です。Mac OS や Linux での開発はサポートされません。 

Unity の拡張機能
Unity エディターには各コンソール用の拡張機能が用意されているので、シーンを構築して開発キットにゲームをデプロイする方法を Unity に指示することができます。モバイルゲームを構築したことがある方であれば、このワークフローにはなじみがあるのではないでしょうか。

プロジェクトをコンソールのハードウェアで実行する
Unity エディター上でゲームを実行することは、実際のコンソールのハードウェアで実行することと同じではありません。開発用 PC の仕様はそれぞれのコンソールと異なり、コンソール自体、仕様がそれぞれ独自のものがあります。この仕様の違いとは、クロック速度、セーブ時間とロード時間、利用できる RAM の量などがあります。RAM については、Nintendo Switch は 4GB、PS4 は 8GB、Xbox One X は 12GB です。

Unity では開発全体を通して、頻繁に開発キット上でゲームを実行することを推奨しています。具体的には、利用できる機器のうち、最も低い仕様のものでテストします。つまり、Xbox One X の代わりに Xbox One、PS4 Pro の代わりに PS4、Nintendo Switch の場合はドックモードの代わりに携帯モードでテストしてください。これは、基準となるパフォーマンスを特定し、それに合わせてコンテンツをオーサリングするのに役立ちます。

パフォーマンスのプロファイリングと最適化を行う

これについてはすでにご存じかもしれませんが、念のため…。コンテンツを最適化する前には、常に忘れずプロファイリングをするようにしましょう。コード変更を強いられるような実パフォーマンス上での問題をピンポイントに特定することができるようになります。  

ゲームが 60 fps で動作するには、各フレームが 1/16 秒(約 17 ミリ秒)以内で動作するよう準備しておく必要があります。フレームがそれよりも長くかかる場合、何に縛られているか(フレーム時間を最も押し上げている要素は何か)を見つけ出す必要があります。一般的によく注意すべきな領域は 2 つあり、それは CPU と GPU が該当します。 

CPU に縛りがある場合、その原因はスクリプトコード、ディスクの読み取り、UI レイアウトの再構築のほか、物理演算が関与している可能性もあります。GPU に縛りがある場合、そのボトルネックを引き起こしているのがグラフィックスパイプラインのどの部分であるか(パーティクル、ポストプロセッシングエフェクトなど)を特定する必要があります。

パフォーマンスのプロファイリングは、各プラットフォームプロバイダーによって提供されるプロファイリングツールや Unity の組み込みのツールを使用して行うことができます。 

プラットフォーム固有のプロファイリングツールを使用すると、ハードウェアの詳細を掘り下げることができます。ある特定の時点での各 CPU コアの動作や、GPU が個々のフレームをどのように構築しているかを把握できます。

Unity でのプロファイリング
Unity のプロファイリングツールは、あらゆるコンソールにわたって機能するほか、開発ツール上で実行するゲームにも使用できます。これにより、コンソールビルドのテストとイテレーションが効率的になります。たとえば、CPU プロファイラーをお使いのコンソール開発キットに直接アタッチし、エディター内でやっているのと同じように、フレームを解析して CPU のスパイクを特定できます。 

また、スクリプトで作成されるガベージコレクションの分散の量を確認することもできます。メモリフットプリントを減らし、ガベージコレクターを実行するときの CPU のスパイクを防ぐのに役立つため、分散を追跡することは重要です。 

ディーププロファイリングとプロファイラーマーカー 
ディーププロファイリングではコードの各行を丹念に調べてくれるので、見逃しやすい分散を特定するのに役立ちます。しかし、収集する際に必要となるデータの量によっては低速になってしまうことも多いので、パフォーマンスのスパイクが発生している部分など、分離しているコードの一部の領域のプロファイリングにのみ使用してください。 

ディーププロファイリングではなくとも、効果的な代替案として、カスタム ProfilerMarker があります。操作は簡単で、profiler.beginsample を配置し、サンプリングしてスクリプトコード内の任意の部分(基本的には疑わしいとされる部分)を論理的にグループ化するだけです。さらに、ProfilerMarker をネストすることで、ゲーム内で何が起こっているかについてより詳しく理解することもできます。これは、すべての beginsample と一致する endsample があることを確認するようにするだけで問題ありません。 

こうすることで、使用しているサンプル名が Unity プロファイラーに表示され、そのブロックの正確なタイミングを確認できるほか、その中のあらゆる分散も表示できます。プロファイラーマーカーはリリースビルドのコンパイルからは除外されるため、後で削除する必要はありません。

プラットフォーム固有のネイティブな API にアクセスする

Unity には、お使いの C# スクリプトからプラットフォーム固有のネイティブな API と直接やり取りするプラグインのセットが備わっています。これにより、コンソール固有の機能にサポートを簡単に追加できます。プラグインには独自のドキュメントとソースコードが備わっています。 

たとえば、Xbox One のすべてのゲーマーは、ゲームのアチーブメントを解放したときに表示されるポップアップに見覚えがあります。このポップアップをトリガーし、その表示方法を制御するには、Xbox One または PS4 固有の API を呼び出す必要があります。

これは、お使いの C# スクリプトコードから、ネイティブプラグインを使用して行うことができます。現在アクティブなプレイヤーをしっかりと把握し、ポップアップの配置をカスタマイズする必要があります。1 回のシンプルな呼び出しで、プレイヤーの正しいアチーブメントを解放できます(以下のコード例を参照)。 

さらに、プラグインにはコンソールの機能と Unity の機能の間のインターフェースが備わっています。プラグイン自体はマネージド C# とネイティブ C++ コードの境界に位置し、ネイティブライブラリとマネージドライブラリのペアで提供されます。ライブラリをプロジェクトの Plugins フォルダーにコピーするだけで使用できます。 

Achievements.cs (C#)

CurrentUser = UsersManager.Users[0];

NotificationManager.SetNotificationPositionHint(
UnityPlugin.NotificationPositionHint.BottomRight);

AchievementsManager.UpdateAchievementAsync(
CurrentUser.Id, Current.UID, “2”, 100, UpdateAchievementCallback);

コンテンツとコードを整理する

ゲームコンテンツを整理してインストールサイズを小さく抑え、パッチ適用を効率的にする

ゲームコンテンツの整理を効率的に始められるように、早めの段階で次の 2 つの質問については自身で確認するようにしておきましょう。  

  • ゲームの機能のうち、プラットフォーム固有のものは何か?この固有のものとは、テクスチャーの解像度、図像だけでなく、ネイティブプラグインのライブラリも含まれる場合があります。ネイティブプラグインについては、適切なインストールサイズを確保するために、関連するプラットフォームにのみ付属させるようにしましょう。  
  • ゲームコンテンツにパッチはどう適用するつもりですか?ゲームをライブに移行したら、バグ修正や追加コンテンツをユーザーに公開する方法を準備してください。

Unity Addressables を使用して動的なゲームコンテンツに対応する 
アセットバンドルは Unity 4 で導入されました。ランタイム中の動的読み込みを目的としたアセットをビルドするための、低レベルのメカニズムです。アセットバンドルを実装することで、開発者はコンテンツをアプリケーションのインストールから分けることができるようになります。これで、初回のダウンロードのサイズを小さく抑えつつ、追加アプリケーションコンテンツ提供時に OTA(Over The Air)インストールの制限を超えることなく、公開済みアプリケーションに対してコンテンツの更新プログラムを定期に配信可能となります。

ところが、実際の制作においてアセットバンドルを使用することは、多くの Unity 開発者にとって面倒な作業となってしまいました。このため、2019 で Addressable Asset System(略して「Addressables」)を導入しました。これにより、「アドレス」によってアセットを簡単にロードする方法が提供され、コンテンツパックの作成とデプロイを簡略化することでアセット管理のオーバーヘッドを処理します。

Addressables では非同期ロードを使用することで、場所を問わずあらゆる依存関係のコレクションをロードすることをサポートします。アセット管理に直接参照、従来のアセットバンドル、Resource フォルダーを使用する場合でも、Addressables にはゲームをより動的にするより簡単な方法が備わっています

Addressables の詳細については、マニュアルを参照してください。 

制約に備える:事前コンパイルのみ機能する
Unity でコンソールゲームを開発するには、IL2CPP スクリプティングのバックエンドが必要です。IL2CPP により、C# スクリプトコードは Microsoft の .NET Compiler Platform(Roslyn)を使用して中間言語コード(IL)にコンパイルされます。次に、Unity の IL2CPP コンバーターにより IL 出力をネイティブ C++ コードに変換され、それが各コンソールプラットフォームの C++ コンパイラーによって、Player(ハードウェア上で実行され、ゲームを実行する実行ファイル)でインポートされて実行される、ネイティブライブラリにコンパイルされます。ランタイムでコードを解釈するのに、この実行ファイルではリソースを使用しないのです。すでにコンパイルされていて、かつ CPU で直接実行できるよう準備されいるので、最高のパフォーマンスを保障します。 

ただし、IL2CPP バックエンドには制約があります。すべてのコードがコンパイル済みで、かつランタイムに準備が完了している必要があるため、事前コンパイル(AOT)のみが実行できることになります。実行時コンパイル(JIT コンパイル)に依存しているタイプの、 C# コードパターンは機能しません。そういったコードパターンは一般的に、ランタイム時にコード生成が必要な場所(リフレクションライブラリ内など)で、かつ特殊な動的タイプで扱われていることがほとんどです。また、アセットストアのパッケージに使用されている場合もあるため、パッケージをダウンロードする前にそれが関連コンソールでテストされているかどうかをパブリッシャーに確認するようにしてください。 

この制約は、シリアル化に関しては課題となる場合がありますが、シリアル化の実行については AOT に適した方法があります。 

その他のヒントについては、コンソール向け開発に関する Oli による Unite セッション全編をご覧ください。

この記事はいかがでしたか?