[Unity] モバイル ゲームのパフォーマンスを最適化する 中国語版

冒頭に書きましたが、私の能力では限界があるので、流し読みして軽くスプレーしました。興味があり、能力のある学生は、オリジナルの英語版を読むことをお勧めします。

元のリンク

抽出コード:p9fu

注:黄色の部分は翻訳が困難なため、英語の原文を参照して理解してください。

ちなみに苦情:ブログの公開ページでワード文書全体を直接コピーすると、写真が常に「アップロード中…」のままになってしまい、一枚ずつしかコピーできません。


プロファイリング_ _ _

Unityには次のツールが付属しています。

プロファイラー

プロファイラーをオンにして、実行時にプロファイラーを実行します。

ビルド時に Development.Build、Autoconnect.Profiler を確認してください

特定のシーンのフレーム数を変更します。

Unity>設定>分析>プロファイラー>フレーム数 

デフォルトは 300 ですが、さまざまなデバッグ最適化シナリオに適用するために最大 2000 まで増やすことができます。(同時に、値が大きいほどCPUとメモリの消費量が多くなります) 

プロファイラービュー:

階層 

経過時間に基づいたサンプルの並べ替えをサポートします。同時に、現在のフレームとマネージド ヒープ メモリ (GC.Alloc) 内の関数呼び出しの数を計算することもできます。

タイムライン 

特定のフレーム時間の視覚的な内訳が表示されます。この視覚化は、さまざまなアクティブなプロセス間およびスレッド間の相関関係を示します。これを使用して、CPU バウンドか GPU バウンドかを判断します。

プロジェクトのプロファイリングを開始する前に、プロファイラーの .data ファイルを保存します。次に、対応する最適化操作を行った後、変更前の .data ファイルと変更後の .data ファイルを比較します (構成 - 最適化 - 比較)。これを繰り返してパフォーマンスを最適化します。

分析と最適化は早期かつ頻繁に行う必要があります

パフォーマンスの分析と最適化は、プロジェクトがオンラインになりかけているときではなく、プロジェクトの初期段階で問題が発生したときに、できるだけ早い段階で常に実行する必要があります。

やみくもに最適化しないでください

ゲームのパフォーマンスが xx の理由によって影響を受けていると推測したり仮定したりしないでください。Unity Profiler と対応するプラットフォームのパフォーマンス分析ツールをタイムリーに使用して、パフォーマンス低下の問題の原因を正確に検出して特定します。

ターゲットデバイスのプロファイル 

Unity Profiler はモバイル プラットフォーム エンジンのすべての部分を収集することはできませんが、iOS と Android にはそれぞれのプラットフォームに対応したパフォーマンス最適化ツールがあります。

iOS:Xcode/Instruments
Android:Android Studio/Android Profiler 

特定のプラットフォームに固有のパフォーマンス分析ツール:

例:Arm Mobile Studio、Intel VTune、Snapdragon Profiler。

プロファイル アナライザー 

このツールは、複数のプロファイラーからデータを収集し、最適化の前後でデータを比較して特定し、関心のある特定のフレームを分析して最適化することができます。これは Profiler の補足および拡張機能であり、より詳細なフレーム データを表示できるようになります。このツールは Unity のパッケージ マネージャーから入手できます。

フレームあたりの特別な時間の予算

理論的には、30fps (フレーム/秒) の各フレームには 33.33ms (1000 ms / 30 fps) かかります。60fps では 1 フレームあたり 16.66 ミリ秒かかります。

ただし、モバイル プラットフォームでは、デバイスが過熱し、CPU と GPU がクロック解除される可能性があるため、この時間を常に使用することはできません。

GPU バウンドか CPU バウンドかを判断する

Gfx .WaitForCommands フラグ: レンダリング スレッドの準備ができており、メイン スレッドがブロックされています

Gfx .WaitForPresent フラグ: メインスレッドは準備完了、GPU はブロックされています

デバイスの温度に注意してください

過熱はパフォーマンスに直接影響を与える可能性があります。

ローエンドデバイスでのパフォーマンスのテスト

下位互換性があり、互換性が最も低いターゲット デバイスでのパフォーマンスのテスト

推奨される観察順序: レンダリング -> メモリ (GC) -> コード スクリプト


メモリ


Unity は自動メモリ管理を使用して、ユーザーが生成したコードとスクリプトを管理します。値型のローカル変数など、より小さなデータの塊がスタック上に割り当てられます。マネージド ヒープに割り当てられた、より大きなデータ ブロックと永続的なデータ ストレージ。

ガベージ コレクター (GC) は、未使用のヒープ メモリを定期的に特定して解放します。ガベージ コレクション操作が自動的に実行されると、ヒープ メモリ内のすべてのオブジェクトが使用されているかどうかがチェックされ、この操作によりゲームがフリーズしたり、パフォーマンスが低下したりする可能性があります。

メモリ使用量の最適化とは、メモリの割り当てと解放をいつ行うべきかを把握し、ガベージ コレクションの影響を最小限に抑えることを意味します。

Unity マネージド ヒープの概要を参照してください。

Unity - マニュアル: マネージドメモリ

メモリプロファイラのスクリーンショットの比較

メモリプロファイラーの使用

この別個のコンポーネントでは、マネージド ヒープ メモリのスクリーンショットを取得でき (パッケージ マネージャーでプレビューおよびダウンロードできます)、断片化やメモリ リークなどの問題を正確に特定するのに役立ちます。

ツリー マップ ビューで変数をクリックすると、メモリに保存されているローカル オブジェクトが見つかります。ここでは、非常に大きなテクスチャやアセットの重複など、一般的なメモリ消費の問題が確認できます。

メモリ プロファイラを使用してメモリ使用効率を向上させる方法を学びます。

https://www.youtube.com/watch?v=I9wB4Cvgz5g

または、Unity 公式ドキュメントを参照してください。

メモリプロファイラー | メモリプロファイラー | 0.2.10-プレビュー.1
 

ガベージ コレクション (GC) の影響を軽減する

Unity は Boehm-Demers-Weiser ガベージ コレクターを使用します。これにより、プログラム コードの実行が停止され、実行が終了したときにのみプログラムの通常の操作が再開されます。(プログラム コードの実行を停止し、作業が終了した場合にのみ通常の実行を再開します)

Bem ガベージ コレクターのリファレンス ドキュメント: C および C++ 用のガベージ コレクター

GC スパイクを引き起こす可能性がある特定の不必要なヒープ割り当てに注意してください。

文字列:

C# では、文字列型は値型ではなく参照型です。

文字列型の不要な作成と操作を減らします。

JSON や XML などの文字列ベースのデータ ファイルの解析は避けてください。データを ScriptableObjects に保存することも、JSON や XML の代わりに MessagePack、Protobuf などの形式を使用することもできます。

Unity 独自の関数呼び出し:

一部の関数はヒープ割り当てを作成することに注意してください。

ループ内で配列を繰り返し操作するのではなく、配列への参照をキャッシュします。

さらに、既存の方法を使用して目的を達成するようにしてください。たとえば、文字列と GameObject.tag を直接比較する代わりに、GameObject.CompareTag(string) メソッドを使用してオブジェクトのタグを決定します (新しく作成された文字列型のガベージが返されるため)。

ボクシング:

値型変数と参照型変数の間の受け渡しは避けてください。この操作は一時オブジェクトを生成し、潜在的なガベージをもたらすためです。たとえば、値の型を強制的にオブジェクト型 (int i = 123; object o = i) に変換します。

コルーチン:

yield ではガベージが生成されませんが、新しい WaitForSeconds オブジェクトを作成するとガベージが生成されます。したがって、WaitForSeconds オブジェクトを生成するたびに作成するのではなく、キャッシュして再利用するようにしてください。

統合言語クエリと正規表現 (LINQ と正規表現):

パフォーマンスの問題がある場合は、LINQ と正規表現の使用を避ける必要があります。どちらも最下位レベルでボックス化操作を実行し、ガベージが生成されるためです。

可能であれば定期的にゴミを収集しましょう

特別な時点でのガベージ コレクションがゲームに影響しないことが確実な場合は、System.GC.Collect を手動で呼び出してガベージ コレクションを実行できます。自分にとって有益なことをいつ行うことができるかを知るには、「自動メモリ管理について」を参照してください: https://docs.unity3d.com/Manual/performance-memory-overview.html

インクリメンタルGCを使用しガベージコレクションのワークロードを軽減する 

プログラムの実行では、インクリメンタル ガベージ コレクターが複数あり、ブロック時間が短く (中断が非常に短く)、実行を多くのフレームに分散してガベージ コレクションの作業負荷を軽減します。1 回の長い中断ではなく。

ガベージ コレクションがアプリケーションのパフォーマンスに影響を与えている場合は、このオプションをオンにして、ガベージ コレクションのスパイクを大幅に削減できるかどうかを確認できます。Profile Analyzer を使用すると、アプリケーションのパフォーマンスが向上するかどうかを検証できます。

 インクリメンタル ガベージ コレクターを使用して GC スパイクを削減する


適応パフォーマンス

Unity と Samsung の適応機能を使用すると、デバイスの温度とバッテリー レベルを監視して、問題が発生する前に適切な調整を行うことができます。たとえば、ユーザーが長時間プレイする場合、

その後、ゲームの詳細レベル (LOD) を動的に下げて、ゲームがスムーズに動作するようにすることができます。適応パフォーマンスにより、開発者はゲームのパフォーマンスを維持しながら、制御された方法でゲームのパフォーマンスを向上させることができます。

アダプティブ パフォーマンス関連の API を通じてアプリケーションを調整でき、いくつかの自動モードも提供します。これらのモードでは、適応パフォーマンスによって、次の主要な指標を通じてゲーム設定が決定されます。

-前のフレームに基づいた希望のフレームレート

-デバイスの温度レベル

-デバイスが熱イベントに近接している

- CPU またはGPUによってバインドされたデバイス

これら 4 つの指標(メトリクス)はデバイスのステータスを決定し適応パフォーマンスは対応する設定を調整および最適化することでパフォーマンスのボトルネックを軽減しますこれは、デバイスの状態を記述するインデクサと呼ばれる整数値を提供することによって行われます(これら 4 つのメトリックはデバイスの状態を決定し、適応パフォーマンスは調整された設定を微調整してボトルネックを軽減します。これは、デバイスの状態を説明するためのインデクサーと呼ばれる整数値を提供することによって行われます)

アダプティブ パフォーマンスは Samsung デバイスのみをサポートしていることに注意してください 

適応パフォーマンスの詳細については、[パッケージ マネージャー] > [適応パフォーマンス] > [サンプル] を選択して、パッケージ マネージャーが提供する例を表示します。各例は特定の変数 (スケーラー) の影響を受けるため、さまざまな変数がゲームにどのような影響を与えるかを確認できます。また、エンド ユーザー ドキュメントを参照して、適応型パフォーマンス構成とその API の適切な使用方法について詳しく学ぶことをお勧めします。

アダプティブパフォーマンスサンプル 

アダプティブ パフォーマンス サンプルの使用 | 適応パフォーマンス | 2.1.1

エンドユーザー向けドキュメント  

アダプティブ パフォーマンス ユーザー ガイド | 適応パフォーマンス | 2.1.1


プログラミングコードのアーキテクチャ

Unity の PlayerLoop には、ゲーム エンジンのコアと対話するための機能が含まれています。このツリー構造には、初期化関連のフレームごとの更新を処理する多数のシステムが含まれています。ゲーム関連のすべてのスクリプトの実行は PlayerLoop に依存します。

プロファイリング ビューを見ると、プロジェクト内のすべてのユーザー コードが PlayerLoop の下にあることがわかります (エディタ関連のスクリプトは EditorLoop の下にあります)。

ユーザー スクリプト、設定、およびレンダリング関連コンテンツは、各フレームの計算と画面上の最終的なレンダリング時間に大きな影響を与える可能性があります。 

次のヒントとテクニックを使用してスクリプトを最適化できます。

Unity PlayerLoop を完全に理解する 

まず、各フレーム ループ中に Unity のコードが実行される順序を必ず理解してください。各 Unity スクリプトの一部の関数は、あらかじめ決められた順序で実行されます。スクリプトの作成ライフサイクル全体を通じて、Awake Start Updateと他のメソッドの違いを明確に理解する必要があります。

スクリプトのライフサイクル全体にわたる関数の実行シーケンスについては、「スクリプト ライフ サイクル フローチャート」を参照してください。

Unity - マニュアル: イベント関数の実行順序

フレームごとに大量のコードを実行しないようにする

コードの一部が本当にフレームごとに実行される必要があるかどうかは、慎重に検討し、注意する価値があります。不要なコードは、 Update LateUpdate 、およびFiexdUpdateから移動できますこれらのメソッドにはフレームごとに実行する必要があるコードを含めることができますが、頻繁に更新する必要のないロジックを含めることは避けてください。可能であれば、変更が発生した場合にのみ、対応するロジックを実行してください。

LayerLoop ライフサイクル図

Update関数を本当に使用する必要がある場合は、n フレームごとにコードを実行することを検討してください。これは、タイム スライスを適用することでコードのワークロードを複数のフレームに分散するための一般的な手法です。次の例では、ExampleExpensiveFunctionメソッドを 3 フレームごとに実行します。

private int interval = 3;

void Update()

{

    if (Time.frameCount % interval == 0)

    {

          ExampleExpensiveFunction();

    }

}

Start / Awake 関数に多くのロジックを記述することは避けてください。

最初のシーンがロードされると、各オブジェクトの次の関数が呼び出されます。

 目覚めてください

— オン有効

- 始める

プログラムの最初のフレームがレンダリングされる前に、これらの関数内に時間のかかるロジックを大量に記述することは避けてください。そうしないと、不必要なロード時間が長くなってしまいます。

最初のシーンをロードする詳細なプロセスについては、次のリンクを参照してください。

Unity - マニュアル: イベント関数の実行順序

空の Unity メソッド イベントを避ける

空の MonoBehaviours であってもリクエストのリソースを占有してしまうため、空の Update や LateUpdate などのメソッドは削除する必要があります。

これらのメソッドを使用して一部の機能をテストする場合は、プリプロセッサ ディレクティブを使用します。

#if UNITY_EDITOR

Void Update()

{

}

#endif

この場合、パッケージ化時の不必要な出費を心配することなく、Update を自由に使用して機能をテストできます。

デバッグログの削除 

大量のログ (特に Update、LateUpdate、FixedUpdate) はプログラムのパフォーマンスに影響します。不要なログ情報はパッケージ化前に無効化できます。

この要件は、条件属性 ( Conditional Attribute ) と前処理ディレクティブを使用して簡単に実現できます。たとえば、次のようにクラスをカスタマイズします。

public static class Logging

{

  [System Diagnostics Conditional(“ENABLE_LOG”)]

  static public void Log(object message)

  {

      UnityEngine Debug Log(message);

  }
}

 

プリプロセッサ ディレクティブを追加してスクリプトを区別する 

カスタム クラスを使用してログを出力します。すべてのログ情報を無効にする必要がある場合は、プレーヤー設定でこの前処理コマンドを削除するだけで、すべてのログ情報が数分で消えます。

文字列パラメータの代わりにハッシュ値を使用する

Unity の最下層は、アニメーター、マテリアル、シェーダーなどの属性を処理するために文字列型名を使用しません。効率を高めるために、すべての属性名にはハッシュ ID が使用されます。ハッシュ ID は、これらの属性を処理するために実際に使用されます。

アニメーター、マテリアル、またはシェーダーで Set メソッドまたは Get メソッドを使用するときは、文字列パラメーターの代わりに整数値を取るメソッドを使用してください。文字パラメータを持つメソッドは文字列型をハッシュ型に変換し、 ハッシュ ID を整数パラメータを持つメソッドに渡すためです(文字列メソッドは単純に文字列ハッシュを実行し、ハッシュされた ID を整数値メソッドに転送します)

Animator.StringToHashを使用してAnimator のプロパティ名を取得し、Shader.PropertyToIDを使用してマテリアル ボールまたは Shader のプロパティ名を取得します。

適切なデータ構造を選択する

フレームごとに数万のデータが継続的に反復されるため、選択したデータ構造が数万回反復する際のパフォーマンスに大きな影響を与える可能性があります。したがって、コレクション内でリスト (List)、配列 (Array)、または辞書 (Dictionary) のいずれを使用するかが特に重要になります。C# では、データ構造に関する一般的なチュートリアルの MSDN ガイドを参照して、自分に合った正しいデータ構造を選択できます。

実行時コンポーネントを追加しないようにする

実行時にAddComponent関数を呼び出すと、かなりの消費が発生します。実行時にこのメソッドをいつ呼び出しても、Unity は現在のオブジェクトに重複コンポーネントやその他の必要なコンポーネントが存在するかどうかを確認するためです。

通常、必要なコンポーネントがすでにバインドされているプレハブを直接インスタンス化すると、パフォーマンスのオーバーヘッドをさらに節約できます。

ゲームオブジェクト( Gameobjects )とコンポーネント(コンポーネント)のキャッシュ

GameObject . Find GameObject . GetComponent、およびCamera . main (2020.2 より前) メソッドはパフォーマンスに非常に負荷がかかるため、 Updateでこれらのメソッドを呼び出すことは避けてくださいこれらのメソッドを呼び出して、 Start中にこれらのインスタンスをキャッシュできます

たとえば、次はGetComponent を繰り返し呼び出す否定的な例です。

void Update()
{
 	Renderer myRenderer = GetComponent<Renderer>();
 	ExampleFunction(myRenderer);
}

代わりに、 GetComponentメソッドを 1 回だけ呼び出して、その戻り値をキャッシュすることができます。そうすれば、毎回GetComponentメソッドを呼び出さなくても、この戻り値をUpdateで再利用できます。

private Renderer myRenderer;
void Start()
{
 	myRenderer = GetComponent<Renderer>();
}
void Update()
{
 	ExampleFunction(myRenderer);
}

オブジェクトプールを使用する

オブジェクトインスタンス化と破棄は、多くの場合、ガベージをもたらし、ガベージ コレクションのスパイクを生成する遅いプロセスです。オブジェクト プールを使用すると、これらのオブジェクト (銃から発射される弾丸など) を頻繁にインスタンス化して破棄するのではなく、再利用またはリサイクル可能な一部のオブジェクトを事前にロードできます。

この例では、オブジェクト プールは再利用できる 20 個の PLayerLaser インスタンスを作成します。

CPU が比較的アイドル状態のときに、再利用できるインスタンスをいくつかインスタンス化します。これらのオブジェクトはコレクションに保存されます。ゲームの実行中に、現在利用可能なオブジェクトを取り出して有効にするだけです。不要な場合は無効にし、破棄するのではなくオブジェクト プールに返します。

これを行うと、プロジェクト内のメモリの管理割り当てを減らすことができ、ガベージ コレクションによって引き起こされる問題を回避できます。

 オブジェクト プール内のすべての PlayerLaser オブジェクトは非アクティブであり、いつでも放出できます。

単純なオブジェクト プール システムを作成する方法については、このドキュメントを参照してください。

オブジェクト プーリングの概要 - Unity Learn

使用ScriptableObjects

固定値または設定をMonoBehavioursではなくScriptableObjectsに保存します。ScriptableObject は、一度設定するだけで済むプロジェクト内のアセットです。GameObjectに直接関連付けることはできません。

ScriptableObjectにフィールドを作成して値または設定を保存し、それらをMonoBehaviourで参照します。

この例では、Inventory という名前の ScriptableObject にさまざまな GameObject 設定が保持されます。 

ScriptableObject でこれらのフィールドを使用すると、Monobehaviour からオブジェクトをインスタンス化するたびに、データの不必要な重複を回避できます。

ビデオ チュートリアル「ScriptableObjects の概要」を通じて、 ScriptableObjects がプロジェクトの最適化にどのように役立つかを学ぶことができます。次のドキュメントを通じて関連知識を学ぶこともできます。

Unity - マニュアル: ScriptableObject


プロジェクト構成

次のプロジェクト設定は、携帯電話のパフォーマンスに影響します。

加速度計の周波数を下げるか無効にします(加速度計の周波数)

Unity はモバイルの加速度センサーを 1秒間に数回プールします。パフォーマンスを向上させるために、ゲームに加速度計が必要ない場合は、この属性を無効にするか、その頻度を減らすことを選択できます。

ゲームで加速度計の周波数を使用しない場合は、必ずこの属性を無効にしてください。

一部の不要なプレーヤーまたは品質設定を無効にする

サポートされていないプラットフォームのプレーヤー設定Auto Graphics API を無効にして、多すぎるシェーダー バリアントの生成を減らしますアプリケーションが古い CPU をサポートしていない場合は、「ターゲットアーキテクチャ」を無効にします。 

[品質]設定で、不要な品質レベルを無効にします。

不要な物理効果を無効にする(物理)

ゲームに物理的効果が必要ない場合は、 [自動シミュレーション][自動同期変換]のチェックを外しますこれらの設定はアプリケーションの効率を低下させ、良いことよりも害を及ぼすことになります。  

適切なフレームレートを選択してください

モバイル ゲームのフレーム レートは、デバイスの電力と熱の間のバランスまたはトレードオフを考慮する必要があります。妥協策として、ゲームを 60fps ではなく 30fps に制限することを検討できます。モバイル側では、Unity のデフォルト設定は 30 フレームです。

Application.targetFrameRate を使用して、実行時にフレーム レートを動的に調整できます。たとえば、特定の遅いシーンや静的なシーンでは、フレーム数を 30 未満に制限することもできます。次に、プレーヤーが実行している間にフレーム レートを上げます。

過度に複雑な階層を避ける

階層を単純化しましょう! ゲームオブジェクトにネストレベルが必要ない場合は、ネスト関係をできるだけ単純化するようにしてください。小規模な階層では、シーントランスフォームをリフレッシュするためにマルチスレッドの恩恵を受けます複雑な階層構造により、より多くの階層変換が行われると同時に、多くの不必要な計算とガベージ コレクションが生成されます。

Transform をより深く理解し、関連付けるために、「階層の最適化」と「Unite」の説明を参照してください。

変換は2 回はなく1 回のみ

同様に、Transform を移動するときは、Transform.SetPositionAndRotationを使用して、オブジェクトの位置と回転を同時に更新できます。これにより、Transform を 2 回更新することによって生じる不要なオーバーヘッドを回避できます。

実行時にGameObject をインスタンス化する必要がある場合、シンプルで効果的な最適化方法は、インスタンス化中に親オブジェクトとその位置と回転の情報を直接設定することです。

GameObject Instantiate(プレハブ、親);

GameObject Instantiate(プレハブ、親、位置、回転);

オブジェクトのインスタンス化の詳細については、スクリプト APIを参照してください。

垂直同期(Vsync)がオンの場合

モバイル デバイスはハーフフレームのレンダリングをサポートしていません。エディターで垂直同期を無効にしても ( [プロジェクト設定] > [品質] )、垂直同期はハードウェア レベルで有効のままです。CPU が十分な速度でリフレッシュできない場合現在のフレームが保持され実質的に fps が低下します


資産_

リソース管理操作 (アセット パイプライン) は、アプリケーションのパフォーマンスに大きな影響を与える可能性があります。経験豊富なテクニカル アーティストは、チームがアセットの形式、パラメータ、インポート設定を定義して必要とするのを支援します。

デフォルト設定に依存しないでください。異なるプラットフォームの書き換えタグを使用して、それに応じてテクスチャや幾何学メッシュなどのリソースを最適化してください。設定が不適切な場合、パッケージング サイズが大きくなり、パッケージング時間が長くなり、メモリ使用量が増加します。特定のプロジェクトのベースライン設定をカスタマイズして最適な設定を確保するには、プリセット機能の使用を検討してください

アート リソースの管理をより効果的に実践するには、このドキュメントを参照してください。

https://docs.unity3d.com/Manual/ImportingAssets.html

または、 Unity Learn Web サイトで「モバイル アプリケーション向けの3D アートの最適化」を学習してください。

テクスチャを正しくインポートする

テクスチャ リソースは多くのメモリ領域を占有する可能性があるため、テクスチャのインポート設定には注意が必要です。通常は、次の提案を参照できます。

小さい最大サイズ:効果が許容できる場合は、最も低い設定を使用します。これを行うと、ロスレスかつ非常に効率的な方法でテクスチャ メモリを削減できます。 

2 のべき乗( POT ) を使用する: Unity では、モバイル テクスチャ サイズが 2 のべき乗 (POT) 圧縮形式 (PVRCT または ETC) である必要があります。

アトラスの使用:複数のテクスチャを 1 つのテクスチャに結合すると、描画呼び出しが減り、レンダリング効率が向上します。Unity SpriteAtlasまたはサードパーティのプラグインTexture Packer を使用してアトラスをパッケージ化できます

[読み取り/書き込みを有効にする] オプションを無効にする:有効にすると、このオプションは(によって占有されるメモリ サイズが 2 倍になりますテクスチャ作成し両方GPU のCPU ほとんどの場合、このオプションは無効にします。実行時にテクスチャを生成する必要がある場合は、 Texture2D .Applyメソッドを通じて生成強制し makeNoLongerReadableパラメータをtrue

不要なミップ マップを無効にする: 2D スプライトや UI グラフィックスなど、一部のテクスチャは画面上でサイズが変更されません。これらはミップマップを必要としません (カメラの位置とその表示効果を確実に変更するには、3D オブジェクトのテクスチャでこのオプションを有効にします)異なります)。

インポート設定を正しく行うと、バンドル サイズの最適化に役立ちます

圧縮されたテクスチャ

以下の例では、2 つのモデルが同じテクスチャを使用しています。ただし、左側のテクスチャ設定のメモリ使用量は右側の 8 倍近くになりますが、表示効果に大きな違いはありません。

非圧縮テクスチャはより多くのメモリを消費します

iOS および Android でAdaptive Scalable Texture Compression (ATSC)を使用します。開発中のゲームの大部分は、ATSC圧縮をサポートする最小スペックのデバイスをターゲットとしています (開発中のゲームの大部分は、ATSC 圧縮をサポートする最小スペックのデバイスをターゲットとしています)。

次の特別な状況:

A7 以下のプロセッサを搭載した iOS デバイス (iPhone5、5S など) は PCVRTC 形式を使用します

2016 年より前の Android デバイスは ETC2 ((Ericsson Texture Compression) 形式を使用します

PVRTC または ETC の圧縮品質が十分に高くない場合、またはプラットフォーム デバイスが ASTC 形式をサポートしていない場合は、16 ビットの代わりに 32 ビット テクスチャの使用を試みることができます。

さまざまなプラットフォームでのテクスチャ圧縮形式の詳細については、次のドキュメントを参照してください。

Unity - マニュアル: プラットフォームごとの推奨、デフォルト、およびサポートされているテクスチャ形式

メッシュのインポート設定を調整する

テクスチャやメッシュなどのリソースを設定を考慮せずにインポートすると、メモリ使用量が大量に増加します。グリッド リソースによって生じるメモリ フットプリントを最小限に抑えます。

圧縮グリッド:グリッドを積極的に圧縮すると、ハードディスクの使用量を削減できます (ただし、ランタイム メモリには影響しません)。メッシュの圧縮とさまざまなパラメータがメッシュの最終的な効果に影響することに注意してください。さまざまな圧縮レベルをテストして、モデルに適したレベルを見つける必要があります。

読み取り/書き込みを無効にする:このオプションをオンにすると、グリッドの 2 つのコピーがメモリにコピーされ、1 つはシステム メモリに保存され、もう 1 つは GPU メモリに保存されます。ほとんどの場合、このオプションは無効にします (Unity 2019.2 以前では、このオプションはデフォルトでオンになっています)。

リグと BlendShapes を無効にする:スケルタル アニメーションと BlendShapesアニメーションが必要ない場合は、いつでもこれらのオプションを無効にしてみてください。

可能であれば法線と接線を無効にする:メッシュのマテリアルに法線と接線が必要ないと判断した場合は、不必要なオーバーヘッドを節約するために法線と接線を無効にします

ポリゴン数を確認する

モデルの精度が高くなるほど、メモリと GPU の使用量も増加します。背景をレンダリングするには500,000 の幾何学的面が必要ですか? (背景ジオメトリには 50 万ポリゴンが必要ですか?)選択したDCC パッケージ内のモデルを削減することを検討してくださいカメラの視点からレンダリングできないいくつかの顔を削除します。高精度メッシュではなく、テクスチャと法線マップを使用してモデルの詳細レベルを表現します。 

AssetPostprocessor を使用してインポート設定を自動化する

AssetPostprocessor を使用すると、アセットをインポートするときにスクリプトを実行できます。モデル、テクスチャ、オーディオ、その他のリソースをインポートする前または後に、いくつかの設定をカスタマイズできます。

アドレス指定可能な資産システムの使用

Addressable Asset System ( Addressable Asset System ) は、リソースを管理するための便利な方法を提供し、「アドレス」 (アドレス) またはエイリアス (エイリアス) によってアセットバンドルをロードできます。この統合システムは、ローカルまたはリモート (CDN) からリソースを非同期にロードできます。

非コード アセット (モデル、テクスチャ、プレハブ、オーディオ、または完全なシーン) をAssetBundlesにパッケージ化する場合、それらをダウンロード可能なコンテンツ (DLC)として分離できます。

次にAddressable を使用して、モバイル アプリの小規模な初期ビルドを作成しますクラウドコンテンツ配信を使用すると、ゲーム コンテンツをホストしてクラウドに配信できるようになりプレーヤーはゲームのリアルタイムの進行状況をクラウドから取得できるようになります(その後、Addressables を使用して、モバイル アプリケーション用の小規模な初期ビルドを作成します。クラウド コンテンツ配信 により、ゲームの進行に合わせて、プレイヤーがゲーム コンテンツをホストし、プレイヤーに配信します。)。

Addressable Asset System のアドレス (アドレス) を使用したリソースのロード 

クリックすると、Addressable Asset System がリソースを管理する方法を確認できます。


グラフィックスとGPUの最適化

Unity は各フレームでどのオブジェクトをレンダリングする必要があるかを決定し、描画呼び出しを生成します。描画呼び出しは、グラフィックス描画 API を呼び出してグラフィックス (三角形など) を描画することですが、バッチ処理 (バッチ) は描画呼び出しのグループをまとめて実行します。

プロジェクトが複雑になるにつれて、GPU 上のワークロードを最適化するための特定のパイプラインが必要になります。ユニバーサルレンダー パイプライン( URP )は現在、シングルパス フォワード レンダリング方式を使用して、モバイル端末に高いグラフィック効果をもたらします(遅延レンダリング テクノロジは将来のバージョンで実装される可能性があります) (ユニバーサル レンダー パイプライン (URP) は 現在、シングルパス フォワード レンダリング方式を使用しています。モバイル プラットフォームに高品質のグラフィックスをもたらすフォワード レンダラー (遅延レンダリングは将来のリリースで利用可能になる予定です)。コンソールや PC からの同じ物理ベースのライティングとマテリアルを、携帯電話やタブレットに合わせて拡張することもできます

次のチュートリアルは、グラフィック効率を向上させるのに役立ちます。

描画呼び出しをバッチ処理する 

一緒に描画されるオブジェクトをバッチ処理すると、描画オブジェクトによって行われる描画呼び出しの数を最小限に抑えることができます。これにより、オブジェクトのレンダリングにおける CPU 消費量が削減され、パフォーマンスが向上します。Unity で次のテクニックを使用して複数のオブジェクトをマージし、描画呼び出しを減らします。

動的バッチ処理:小さいメッシュの場合、Unity は CPU 上で頂点をグループ化し、変換し、すべてを一度に描画できます。注: この機能は、十分なローポリ メッシュがある場合にのみ使用してください(頂点属性が 900 未満、頂点数が 300 未満)。動的バッチ処理では、これらより多くの頂点を持つオブジェクトは結合されないため、これを有効にすると、CPU がフレームごとに小さいメッシュを見つける必要があるため、CPU 時間が消費されます。

静的バッチ処理:一部の静的オブジェクトの場合、Unity は同じマテリアルを使用するオブジェクトをバッチ処理して描画呼び出しを減らすことができます。静的バッチ処理は動的バッチ処理よりも効率的ですが、より多くのメモリ領域を使用します。

GPU インスタンス化:同一のオブジェクトが多数ある場合この技術はグラフィックス ハードウェア

SRP バッチ処理: Universal Render Pipeline Asset下のAdvancedメニューで、 SRP Batcherをオンにしますこのオプションを使用すると、シーンに応じてCPU のレンダリング時間を高速化できます。 

これらのバッチ処理テクニックを活用してゲームオブジェクトを調整します。 

フレームデバッガーを使用する

フレーム デバッガーは、各フレームがさまざまな描画呼び出しでどのように構成されているかを示しますこれは、シェーダ プロパティを監視し、ゲームがどのようにレンダリングされるかを分析するのに役立つ非常に便利なツールです。

Frame Debugger の新機能については、次のドキュメントを通じて学習できます。

フレーム デバッガーの操作 - Unity Learn

動的ライトを多用しすぎないようにする

従来のフォワード レンダラーと比較して、ユニバーサル レンダリング パイプライン (URP) は描画呼び出しの数を大幅に削減します。モバイル アプリに動的ライトを追加しすぎないようにしてください。ダイナミック メッシュでカスタム シェーダ エフェクトまたはライト プローブを使用するか、スタティック メッシュでライティングをベイク処理することを検討してください。

この比較表を使用すると、ユニバーサル レンダリング パイプライン (URP) と組み込みレンダリング パイプライン (組み込みレンダリング パイプライン) のリアルタイム ライティングの違いを確認できます。

機能比較表 | ユニバーサルRP | 10.4.0


フレーム デバッガーは各フレームを個別のステップに分割します

シャドウを無効にする

MeshRenderer とライトではシャドウ キャストが無効になります。したがって、可能な限りシャドウを無効にして描画呼び出しの数を減らします。

キャラクターの下にブラー テクスチャを備えた単純なメッシュまたはクワッドを配置して、影を偽装することができます。または、カスタム シェーダを使用して影を作成します。

描画呼び出しを減らすためにキャストシャドウを無効にします

ライティングをライトマップにベイクする

グローバル イルミネーション (GI) を使用して、静的ジオメトリに豪華な照明を追加します。Contribute GI属性を使用してオブジェクトをマークすると、高品質のライティング情報をライトマップの形式で保存できます。

実行時にベイク処理されたシャドウとライトをレンダリングするときにパフォーマンスへの影響はありません。より優れた CPU と GPU により、グローバル ライトのベイク処理を高速化できます。

GI への貢献をオンにする

ライトマッピング設定 (Windows > レンダリング > ライティング設定) とライトマップ サイズを調整してメモリ使用量を制限します。

Unity でライトマッピングを開始する際には、照明の最適化に関するこのガイドとこの記事を参照してください。

ライトレイヤーの使用

複数の複雑なライトを使用するシーンでは、さまざまなレベルを使用してすべてのオブジェクトを区別し、カリング マスク機能を使用してさまざまなライトの影響をさまざまな範囲に制限できます。

レイヤー機能により、異なるライトの影響を異なる範囲に制限できます。

移動するオブジェクトに対するライトプローブの使用

ライト プローブは、シーン内の空きスペースのベイクされたライティング情報を保存し、高品質のライティング効果 (直接的および間接的) を提供します。彼らは、動的照明よりも計算がはるかに速い球面調和関数を使用しました

ライトプローブは背景の動的オブジェクトを照らします

詳細レベル( LOD )を使用する

オブジェクトが移動すると、LOD機能はオブジェクトをより単純なメッシュに切り替え、より単純なマテリアルとシェーダーを使用できるため、GPU パフォーマンスの向上に役立ちます。

詳細については、 Unity Learn Web サイトのWorking with LODsコースを受講してください。

LOD グループを使用したメッシュ インスタンス 

 

異なる解像度での同じモデルのメッシュ頂点の違い

オクルージョンカリングを使用して非表示のオブジェクトを削除する

他のオブジェクトの背後に隠れている一部のオブジェクトは引き続きレンダリングされ、リソースを消費する場合があります。オクルージョン カリングを使用してそれらを破棄します。

カメラの視野外の錐台カリングは自動化され、オクルージョン カリングはベイクイン プロセスです。オブジェクトを静的オクルーダーまたはオクルーディーとして設定し[ウィンドウ] > [レンダリング] > [オクルージョン カリング]ダイアログ ボックスでベイク処理するだけです。これはすべてのシナリオに適しているわけではありませんが、ほとんどの場合、カリングを使用するとパフォーマンスが向上します。

詳細については、「オクルージョン カリングの操作」チュートリアルをクリックしてください。

ネイティブのモバイル解像度に注意してください

携帯電話やタブレットはますます高性能になり、解像度もますます高くなっています。

Screen . SetResolution(width, height, false)を使用して出力解像度を下げ、パフォーマンスを向上させます。複数の解像度を構成して、ゲームのグラフィックスとパフォーマンスのバランスをとります。

カメラの数を制限する

すべてのカメラは、意味のある作業を実行しているかどうかに関係なく、パフォーマンスのオーバーヘッドを発生します。レンダリングに必要なカメラ コンポーネントのみを使用してください。一部のローエンド デバイスでは、各カメラに最大 1ms の CPU 時間がかかる場合があります。

複雑なシェーダ(シェーダ)を避けるようにしてください。

ユニバーサル レンダリング パイプライン (URP) はすでにいくつかの自己照明シェーダーと非照明シェーダーを提供しており、モバイル プラットフォーム用に最適化されています。シェーダの変更は実行時のメモリ使用量に大きな影響を与える可能性があるため、最小限に抑えてください。ユニバーサル レンダリング パイプラインによって提供されるシェーダーがニーズを満たせない場合は、シェーダー グラフを使用してシェーダーをカスタマイズできます。ここをクリックすると、シェーダー グラフを使用してシェーダーを視覚的に生成する方法が表示されます。

シェーダーグラフを使用してカスタムシェーダーを作成する

オーバードローアルファブレンディングを削減する

不要な透明または半透明の画像を描画しないでください。オーバードローとアルファ ブレンディングは、モバイル プラットフォームのパフォーマンスに深刻な影響を及ぼします (モバイル プラットフォームは、結果として生じるオーバードローとアルファ ブレンディングによって大きな影響を受けます)。ほぼ透明な画像やエフェクトを重ねないでください。RenderDocグラフィックス デバッガーを使用して、オーバードローを検査できます。

画面の後処理の使用を削減

フルスクリーン画面の後処理効果は、ゲームのパフォーマンスを大幅に低下させます。芸術的な効果を開発するときは、画面の後処理効果を注意して使用してください。

モバイルアプリでシンプルな後処理エフェクトを使用する

Renderer .マテリアルの使用には注意が必要です

スクリプトでRenderer.materialを使用すると、新しいマテリアルがコピーされて返されますこれは、シェーダーを含むバッチ処理されたコンテンツに影響します。バッチ オブジェクトのマテリアルにアクセスする場合はRenderer.materialの代わりにRenderer.sharedmaterialを使用します。

SkinnedMeshRenderer の最適化

スキンメッシュのレンダリングは、パフォーマンスに非常に負荷がかかります。SkinnedMeshRendererを使用するすべてのオブジェクトが実際にそれを必要とすることを確認してください。ゲームオブジェクトが特定の時間にのみアニメーションを必要とする場合は、BakeMesh関数を使用して静的アクションでスキン メッシュをフリーズし、実行時により単純なMeshRendererに切り替えることができます (ゲームオブジェクトが時々アニメーションを必要とする場合は、BakeMesh を使用します)スキン メッシュを静的ポーズでフリーズし、実行時により単純な MeshRenderer に切り替える関数)

リフレクションプローブの使用を減らす

Reflection Probe はリアルな反射効果を作成できますが、非常にコストがかかる可能性があります。低解像度のキューブマップ、カリング マスク、およびテクスチャ圧縮を使用して、実行時の効率を向上させることができます。 


ユーザーインターフェース

UnityUI (UGUI) もパフォーマンスの問題の原因となることがよくあります。Canvas コンポーネントの UI 要素は、グリッドを生成および更新し、描画呼び出し命令を GPU に送信します。この処理はパフォーマンスを消費することが多いため、UGUI を使用する場合は次の点に注意してください。

キャンバスを合理化する

数千の要素を含む巨大な Canvas がある場合、個々の UI 要素を更新すると Canvas 全体が強制的に更新されるため、CPU のスパイクが発生する可能性があります。

複数の Canvas をサポートする Unity の機能を活用できます。次に、更新頻度の違いに基づいて UI 要素を分類します。静的な UI 要素を Canvas の下に配置し、動的な UI 要素を格納するための小さなサブキャンバス (サブキャンバス) を作成します。

各キャンバス上のすべての UI 要素が同じ Z 値、シェーダー、テクスチャ マップを使用していることを確認してください。

非表示の UI 要素を非表示にする

ゲームには、たまにしか表示されない UI 要素がいくつかある場合があります (プレイヤーが負傷したときに 1 回だけ表示される体力バーなど)。これらの非表示の UI 要素がまだアクティブな場合でも、描画呼び出しが生成されます。したがって、非表示の UI 要素をすべて直接無効にして、再度表示されるまで無効にし、その後再度有効にします。

Canvas を非表示にする必要がある場合は、GameObject 全体を無効にするのではなく、Canvas コンポーネントを無効にします。これにより、メッシュと頂点の再描画が回避されます。

GraphicRaycaster の使用を減らしRaycast Target を無効にする

画面上のタッチやクリックなどの入力イベントの検出には、GraphicRaycaster コンポーネントが必要です。これは、画面上のすべての入力ポイントを検出して、それが UI の RectTransform 上にあるかどうかを検出することによって行われます。

階層パネルで、Canvas 上のデフォルトの GraphicRaycaster コンポーネントを削除します。次に、インタラクションが必要な要素 (ボタン、スクロール四角形など) に GraphicRaycaster コンポーネントを個別に追加します。

デフォルトで有効になっている「反転グラフィックを無視」オプションを無効にします。

同様に、Raycast Targetを必要としないすべてのテキストと画像でこのオプションを無効にします。複雑な要素で構成された UI では、小さな変更によって不必要な計算が発生します。

可能であれば、レイキャスト ターゲットを無効にします

レイアウト グループ コンポーネントは注意して使用してください

レイアウト グループの更新効率は比較的低いため、このコンポーネントは注意して使用してください。コンテンツが動的でない場合は、それらを完全に避け、代わりに比例レイアウトのアンカーを使用してくださいまたは、レイアウト グループがUI レイアウト設定を完了した後、コード内で無効にします。

動的要素を管理するためにレイアウト グループ (水平、垂直、グリッド) コンポーネントが本当に必要な場合は、パフォーマンスを向上させるためにコンポーネントをネストしないでください。

レイアウト グループは、特にネストして使用した場合、パフォーマンスに影響を与える可能性があります。

大きなリスト ビューグリッドビューはできるだけ使用しないでください

大きすぎるリストとグリッド ビューは、パフォーマンスに非常に負荷がかかります。巨大なリストまたはグリッド ビュー (数百の製品で構成される在庫ページなど) を作成する必要がある場合は、製品ごとに新しい UI 要素を作成する代わりに、UI 要素オブジェクトの小さなプールを再利用できます。さらに理解するには、この例を参照してください

重複する要素を多く避ける

多数の UI 要素を過度に階層化すると (カード ゲームの大量のカードのスタックなど)、オーバードローが発生します。コードをカスタマイズして、ゲームの実行中に UI 要素をより少ないレイヤーとバッチに動的にマージします。

複数の解像度アスペクト比を使用する

現在、多くのモバイル デバイスはまったく異なる解像度と画面サイズを使用しており、各デバイスが最高のユーザー エクスペリエンスを実現できるように、さまざまなデバイスに代替バージョンの UI が提供されています。

デバイス シミュレーターを使用して、サポートされているほとんどのデバイスで UI がどのように表示されるかをプレビューしますXCodeおよびAndroid Studioで仮想デバイスを作成することもできます。

デバイス エミュレーターを使用してさまざまな画面形式をプレビューする

全画面 UI を使用する場合は他のすべてを非表示にします

一時停止ページと開始ページがシーン内のすべてをカバーしている場合は、シーン内の 3D カメラを無効にしてレンダリングします。同様に、上部の Canvas の背後に隠れているすべての Canvas 要素を無効にします。

このページは更新に 60fps を必要としないため、画面に全画面 UI が表示される場合は、リフレッシュ レートApplication . targetFrameRateを下げることを検討してください。

キャンバスのレンダリング モードでワールド スペースとカメラ スペースを選択するときは、忘れずにカメラを割り当ててください。 

Event CameraまたはRender Cameraに値が割り当てられていない場合、 Unity はCamera.main を強制的に割り当てるため、不必要なパフォーマンス コストが発生します。  

許可されている場合、キャンバスのレンダリングモードはScreen Space–Overlayの使用を検討できます。このモードでは、別のカメラを指定する必要はありません。 

スペース レンダリング モードを使用する場合は、対応するカメラがイベント カメラに割り当てられていることを確認してください。 


オーディオ_ _ _

通常、オーディオ リソースはパフォーマンスのボトルネックにはなりませんが、最適化することでメモリを節約できます。

可能な限りモノラル音声を使用してください

3D 空間オーディオを使用する場合は、オーディオをモノラルに設定するか、Force To Monオプションを有効にすることをお勧めします。スペースの配置に使用されるマルチチャンネル オーディオは、実行時に強制的にモノラル オーディオ ソースに変換され、このプロセスにより CPU とメモリの使用量が増加します。

可能な限り、未加工の非圧縮 WAV ファイルをリソースとして使用してください

何らかの圧縮形式 (MP3、Vorbis など) を使用している場合、Unity はパッケージ化時にそれを解凍します (二次圧縮)。これら 2 つのプロセスにより、最終的なオーディオ効果が不満足になります。

オーディオを圧縮してビットレートを下げる

圧縮によりオーディオ サイズとメモリ使用量を削減します。

——Vorbis形式を使用してみてください(ループしないオーディオの場合はMP 3形式を使用してください)。

——短くて頻繁に使用される音声には、 ADPCM形式を使用できます(足音、射撃音など)。この圧縮形式は、非圧縮PCMよりも再生時のデコード速度が速くなります。

モバイル効果音リソースのサンプリング レートは最大 22050hz を超えてはなりません。通常、低いオーディオ設定を使用しても最終的なオーディオ品質には特に影響はありません。ただ耳で感じてください。

AudioClipのインポート設定の最適化

適切な負荷タイプを選択してください

この設定はリソースのサイズによって異なります。

——小さいサイズのオーディオ (200kb 未満) の場合は、[読み込み時に圧縮解除]を選択する必要があります。これにより、オーディオが元の 16 ビット PCM 形式のデータに解凍され、CPU とメモリの使用量が増加するため、このオプションは短いオーディオにのみ適しています。

——中規模のオーディオ (200kb 以上) では、 [メモリ内で圧縮]を選択する必要があります

——大きいサイズの音声(BGM)はストリーミングに設定してください。それ以外の場合、リソース全体が一度にメモリにロードされます。

ミュートされたオーディオをメモリからアンロードする(AudioSources)

ボタン機能を実装する場合、音量を直接0に調整しないでください。プレーヤーがこのオプションを頻繁に切り替え (ミュート/ミュート解除) しない限り、AudioSourceコンポーネントを破棄 ( Destroy )してメモリからアンロードできます。


アニメーション_

Unity のアニメーション システムは非常に高度です。可能であれば、次の設定を使用してモバイル アニメーションを制限します。

汎用リグとヒューマノイドリグを使用する

デフォルトでは、アニメーション モデルが Unity にインポートされると、Generic Rig に設定されますが、キャラクター アニメーションを使用する場合、開発者は通常、Humanoid Rig に設定します。

ユニバーサル アニメーションと比較すると、ヒューマノイド アニメーションは、使用していない場合でもフレームごとに逆ダイナミクスとアニメーション リダイレクトを計算する必要があるため、CPU 計算時間が 30 ~ 50% 増加します。Humanoid Rig アニメーションでこれらのアトリビュートを使用しない場合は、アニメーションを Generic Rig に設定することを選択してください。

アニメーション コントローラー( Animator )の過度の使用を避ける

アニメーターは主にヒューマノイド キャラクターを操作するために使用されますが、単一の値 (UI 要素の透明度チャネルなど) の変更を制御するためにもよく使用されます。Animator の過度の使用、特に UI 要素との組み合わせ。可能な限り、モバイルでは従来のアニメーション コンポーネントを使用してください。

単純なアニメーション効果 (DOTween など) を実現するには、トゥイーン アニメーションの使用またはサードパーティのプラグインの使用を検討できます。

アニメーターはパフォーマンスを非常に重視する場合があります


物理学_

Unity の組み込み物理システム (Nvidia PhysX) は、モバイル デバイス上で非常にパフォーマンスを重視します。次のヒントを参照すると、いくつかのフレームを保存するのに役立ちます。

設定を最適化する

PlayerSettings で、可能であればPrebake Collision Meshesオプションをオンにします。

プリベイクコリジョンメッシュを有効にする

物理設定が設定されていることを確認してください([プロジェクト設定] > [物理])レイヤー衝突マトリックスを可能な限り単純化します  

[自動同期変換] を無効にし[衝突コールバックの再利用]を有効にします。

物理設定を変更してパフォーマンスを向上させる 

パフォーマンスの問題については、プロファイラーの物理モジュールに注意してください。

コライダーを単純化する

メッシュ コライダーはパフォーマンスに非常に負荷がかかります。より複雑なメッシュ コライダーをより単純なプリミティブまたはメッシュ コライダーに置き換えて、元の形状に近づけます

オリジナルまたは単純なメッシュ コリジョン ボックスを使用する

物理的方法を使用して剛体を移動する(Rigidbody)

剛体を移動するには、MovePosition クラスメソッドまたはAddForceクラス メソッドを使用します。Transformコンポーネントを直接移動すると、物理世界の再計算が行われるため、より複雑なシーンではパフォーマンスが大幅に消費されます。Updateではなく、 FixedUpdateでオブジェクトを移動します。

固定タイムステップの変更

プロジェクト設定のデフォルトの固定タイムステップは 0.02 (50Hz) です。ターゲット フレーム レートに応じてこの設定を変更します (たとえば、30fps の場合は 0.03 に設定します)。

それ以外の場合、実行時にフレームをドロップすると、Unity が 1 つのフレーム内でFixedUpdateメソッドを複数回呼び出すことになり、物理を多用するコンテンツで CPU パフォーマンスの問題が発生する可能性があります)。

最大許容タイムステップこの設定では、フレームがドロップされたときに実行できる物理計算とFixedUpdateイベントの数を制限します。この値を下げると、パフォーマンスが低下するにつれて物理演算とアニメーションが遅くなりますが、フレームごとに与える影響は減少します。

ターゲット フレーム レートに合わせて固定タイムステップを変更し、パフォーマンスの問題を軽減するために最大許容タイムステップを下げます。

物理デバッガーで視覚化する

[物理デバッグ] ウィンドウ ( [ウィンドウ] > [分析] > [物理デバッガー]) を使用して、衝突と不一致の問題のトラブルシューティングと解決を行います。このウィンドウには、ゲームオブジェクトが衝突できるオブジェクトが色分けされた形で視覚的に表示されます。

物理デバッガーは、物理オブジェクトがどのオブジェクトと相互作用および衝突できるかを直感的に示します。

関連情報の詳細については、Unity 公式ドキュメント「Physics Debug Visualization」を参照してください。
 


ワークフローとコラボレーション

Unity でプロジェクトをパッケージ化することは大規模な作業であり、通常は多くの開発者が関与します。プロジェクト設定がチームにとって最適であることを確認してください。

バージョン管理を使用する

誰もが何らかのバージョン管理を使用する必要があります。エディタ設定のアセットシリアル化モードが強制テキストに設定されていることを確認してください 

サードパーティのバージョン管理ツール (Git など) を使用している場合は、バージョン管理設定のモードがVisible Meta Filesに設定されていることを確認してください   

Unity には、シーンとプレハブをマージするための組み込みマークアップ言語 (YAML、人間が読めるシリアル化言語) ツールがすでに組み込まれています。関連情報の詳細については、Unity の公式ドキュメント「 Smart Merge」を参照してください。

バージョン管理ツールはチーム作業に不可欠です。これはバグを特定し、問題のあるバージョンを見つけるのに役立ちます。ブランチとタグを使用してプロジェクトのバージョンとリリースを管理するなど、適切な開発プロセスに従ってください。

Plastic SCM は、ゲーム開発のために Unity によって公式に推奨されているバージョン管理ツールです。

より大きなシーンを分割する

サイズが大きすぎるため、単一のシーンでは共同開発には適していません。レベルを小さなシーンに分割すると、アーティストとデザイナーが開発で共同作業しやすくなり、競合の可能性も最小限に抑えられます。

実行時に、LoadSceneMode . Additiveパラメーターを追加することで、SceneManager . LoadSceneAsyncを使用してシーンを読み込むことができます。

使用されていないリソースを削除する

サードパーティのプラグインやライブラリにバンドルされている未使用のリソースがあることに注意してください。これには、テストに使用されるいくつかのリソースとスクリプトが含まれます。これらは、手動で削除しなかった場合にパッケージに含まれている可能性があります。未使用のリソースは最初に削除する必要があります。

Unity  Accelerator を使用して共有を高速化する

Unity Accelerator は、Unity エディターのコンテンツをより速く共有できるようにするコラボレーション ( Collaborate ) サービス プロキシおよびキャッシュです。チームがローカル ネットワークで作業している場合は、プロジェクトの一部を再構築する必要がないため、ダウンロード時間が大幅に短縮されます。Unity Teams Advancedを使用する場合、アクセラレータはリソースを共有することもできます。


Unity の成功事例( Unity Integrated Success ) 

Unityとの公式連携の成功例と言えそうだ。

興味のある方は、次のアドレスにアクセスして詳細をご覧ください。

Unity の統合の成功

お問い合わせフォーム


結論_

Unity ブログ、または#unitytips タグを使用してUnity コミュニティおよびUnity 学習フォーラムで追加の最適化に関する知識、ヒント、ニュースを入手できます

パフォーマンスの最適化は幅広いトピックです。モバイル デバイスのハードウェアがどのように動作するか、およびそのパフォーマンスの制限を理解します。プロジェクトに最適かつ最も効果的なソリューションを見つけるには、Unity の公式クラス、コンポーネント、アルゴリズム、データ構造、対応するプラットフォームのパフォーマンス分析ツールを理解し、学習する必要があります。

もちろん、あなたの創造性も過小評価することはできません。

おすすめ

転載: blog.csdn.net/qq302756113/article/details/123872531
おすすめ