前書き
ゲームを作るとき、ゲーム開発の最も重要な側面の1つである最適化を見落としがちです。その結果、遅延が発生し、FPSが低くなります(すべてが実際に実行されている場合は、ハイエンドデバイスでも発生することがあります)。ほとんどの人は常にゲームの最適化を最後のステップと見なします。これが最初の間違いです。常にリストの最初の項目である必要があります。
すべてのビルドで習慣を過大評価することはできません。毎日、新しいメカニックや新しい照明設定、または物理ベースのシステムをゲームに追加するときは、常にビルドをチェックして、これらに起因するパフォーマンスの問題があるかどうかを確認してください。変更は良いゲーム開発の練習です。
プロジェクトの開始直後からパフォーマンスを最適化するために時間をかけないと、最終段階であなたとあなたのゲームに問題が発生する可能性があります。ここでは、過去5年間の私の過ちから学んだいくつかの実践的な教訓に基づいて、ゲームのパフォーマンスを向上させる方法についての考えとヒントを共有したいと思います。
ゲームのプロファイル
プロファイラーはリストの最初であり、ゲームのパフォーマンスを監視して実際にパフォーマンスの問題を引き起こしているものを確認するためのUnityでの私のお気に入りのツールの1つです。これは、エディターのさまざまな変更に対してゲームがどのように反応するかを詳細に理解するのに非常に役立ちます。
プロファイラーは[ウィンドウ]-> [分析]-> [プロファイラー]
にあります。CPUとGPUの使用状況、レンダリング、物理、オーディオなどのカテゴリが表示されます。エディターはテスト中のプロジェクトのパフォーマンスに影響を与え、これはプロファイリング情報の有効性に影響を与える可能性があるため、エディターでのプロファイリング(エディタープロファイリング)に依存することはできません。正確なプロファイリングデータを取得するには、別のビルドを作成することをお勧めします。
リモートプロファイリング
これを機能させるには、Android SDKをインストールし、JDKとUSBデバッグを接続する必要があります。メカニックやUIスケーリングなどに関しては、ゲームのパフォーマンスをテストすることをお勧めします。上記と一緒に実際のゲームパフォーマンスをテストすることは言うまでもありません。ゲームの実際のパフォーマンスをテストするには、カスタムプロファイリングビルドを作成する必要があります。
リモートプロファイラーに接続するには、[編集]> [プロジェクト設定]> [エディター]に移動し、[デバイス]で[任意のAndroidデバイス]を選択します。
プロファイリングビルド
Unityがプロファイリング可能なビルドにアクセスできるようにするには、ビルド設定で「開発ビルドまたはディーププロファイリングサポート」と「プロファイラーの自動接続」を有効にしてから作成する必要があります。これにより、Unityエディターでビルドを自動的にリンクできます。
入札の準備ができたら、UnityProfilerウィンドウを閉じずにゲームを開きます。Unityは、プロファイラーウィンドウにゲームの現在のビルドのパフォーマンスデータを自動的に表示するようになりました。
プロファイラーの詳細については、こちらをご覧ください。
GameObjectsのバッチ処理
バッチ処理は、Draw呼び出しの数を減らすことでパフォーマンスを向上させるための非常に優れた手法です。これは、1回のDraw呼び出しで複数の同様のGameObjectのレンダリングをグループ化することです。バッチ処理方法には、静的と動的の2つのタイプがあります。バッチ処理にはいくつかの制限があります。スキンメッシュ、ファブリック、および一部のレンダリングコンポーネントをバッチ処理することはできません。
静的バッチ処理
静的バッチ処理は、GameObjectが静的である場合は常に使用されます。このような静的ゲームオブジェクトは、移動、拡大縮小、または回転してはならず、バッチ処理を機能させるには、すべての静的ゲームオブジェクトに同じマテリアルを使用する必要があります。
GameObjectがPlayerと相互作用しない場合、またはTransformを変更しない場合は、建物や道路など、ゲーム内のほとんどの環境で静的バッチ処理を使用するのが最適です。
動的バッチ処理
動的バッチ処理は、GameObjectsが同じマテリアルを使用する必要があるという点で静的に似ていますが、移動するオブジェクトを静的にすることなくグループ化できます。基本的に、Unityは、同じマテリアルを使用する場合、GameObjectを同じ描画呼び出しに自動的にロードできますが、Unityに従って、動的バッチ処理の制限がいくつか課せられます。
- 動的GameObjectのバッチ処理には、頂点ごとに特定のオーバーヘッドがあるため、バッチ処理は、頂点が300以下、頂点属性が900以下のメッシュにのみ適用されます。
- Shader Vertex Position, Normal UV, 300 , Shader Vertex Position, Normal, UV0, UV1 Tangent, 180 .
- : .
- GameObject- , transform (, GameObject A +1 GameObject B –1 ).
- Material , GameObject- , . Shadow Caster.
- : / . , GameObject- .
- Multi-pass .
- Unity , . « » .
- Legacy Deferred ( ) , GameObject .
動的バッチ処理は、パーティクルシステム、レンダリングライン、およびトレイルレンダリングとメッシュの動作が異なります。
- Unityは、互換性のあるレンダラータイプごとに、すべてのバッチコンテンツを1つの大きなVertexバッファーに収集します。
- レンダラーは、バッチマテリアルの状態を設定します。
- Unityは、頂点バッファをグラフィックスデバイスにバインドします。
- Unityは、バッチ内のレンダラーごとに、Vertex Bufferのオフセットを更新してから、新しい描画呼び出しを送信します。
Simple Mesh Combine、Bakeryなど、Assetstoreの一部のアセットを使用してバッチ処理を改善する方法は他にもあります。また
Mesh.CombineMeshes
、複数のメッシュを1つに結合することもできます。これは、パフォーマンスの最適化に最適です。
あなたの照明を焼く
大まかに言えば、リアルタイム、ベイクド、ミックスの3つの照明モードがあります。
リアルタイムは最高ですが、パフォーマンスで支払う必要があります。シーンに直接光をもたらし、ライトとゲームオブジェクトがシーン内を移動するたびにフレームごとに更新し、照明を即座に更新します。
ステージで照明を焼くオプションがある場合は、特にモバイルデバイスをターゲットにしている場合は、生産性の向上に理想的であるため、必ず使用してください。希望の外観を実現するには、ステージで低照明を使用するのが常に最善です。
このように、すべてのライトは、ライトマップベーキングと呼ばれるプロセスでオフラインで事前に計算されます。 GameObject Lightmap静的フラグを設定すると、Unityは、GameObject Light、シャドウ、スペキュラーライト、およびソフトシャドウに関する情報をシーンに触れるテクスチャに焼き付けます。ただし、ライトマップにはいくつかの制限があり、ライトマップ静的フラグで選択したオブジェクトの照明を動的に更新することはできません。
数ヶ月前の空き時間にSCIFIシーンを作成しましたが、これが焼き照明の仕組みの最良の例だと思います。もちろん、私はエミッションを使用しました。
このSCIFIシーンがどのように作成され、どのようにこの外観を実現したかについての概要に興味がある人がいたら、私に知らせてください。別の記事をこれに捧げることができます。
, !
これは、Unityオクルージョンを使用してゲームのパフォーマンスを向上させるための非常に良い方法です。一般に、オクルージョンカリングとは、Unityが他のゲームオブジェクトによってカメラの視点から完全に隠されている(オクルージョンされている)ゲームオブジェクトを表示しないことを意味します。
オクルージョンウィンドウを開くには、[ウィンドウ]-> [レンダリング]-> [オクルージョンカリング]に移動します。
ミステリーフォレストシーンでこの外観をどのように実現したかに興味がある場合は、別の記事を書くことができます。
興味のある方はこちらの動画をご覧ください。
twitter.com/i/status/1096336962259021824
デフォルトでは、UnityはFrustum Cullingを適用します。つまり、カメラの視線のみを表示し、すべてのオブジェクトを表示します。たとえば、カメラが壁を見ている場合、その壁の後ろにあるすべてのオブジェクトもレンダリングされます。これはまったく必要ないので、シーンにオクルージョンカリングを追加する必要があります。
これが、オクルージョンカリングを使用する必要がある理由です。つまり、カメラは壁のみをレンダリングし、背後にオブジェクトはありません。
続きを読む: