This document is about: QUANTUM 2
SWITCH TO

物理パフォーマンスと最適化

イントロ

リアルタイムのインタラクションが発生するマルチプレイヤーゲームでは、プレイヤーに可能な限りスムーズな体験を提供するために、ゲームのパフォーマンスが非常に重要になります。

物理演算が常に原因というわけではありませんが、物理演算がボトルネックになることはよくあります。

プロファイリング

これ以上何かをする前に、問題が実際に物理システムに起因していることを確認したい。

Quantum Graph Profiler

Quantum Graph Profilerは、グラフィックスやUnityスクリプトだけでなく、すべてのシステムのパフォーマンスをプロファイリングするツールです。これは主に、Unity関連の何かがパフォーマンスの問題を引き起こしているかどうかを判断するのに役立ちます。

タスクプロファイラ

このツールは、 Quantum Simulation の各システムの実行時間を評価するために使用します。

一般的に、これらのツールで物理に関連するものが検出されない場合、あなたが直面している問題はおそらく物理ではありません。

Quantumのプロファイリングの詳細については、以下を参照してください: Profiling

ブロードフェイズの最適化

物理エンジンは、システムセットアップでそれぞれのシステムによってスケジュールされた一連のタスクです。 各フレーム、これらのタスクは:

  1. シミュレーション内の物理コンポーネントを持つエンティティの物理エントリを作成し、エントリを収集します。

  2. ブロードフェーズ: 詳細な評価を行うために、重複する可能性のあるペアを検出します。このステップは、総当たり的な O(n2) 検出を回避するために重要です。

  3. 狭相: 前のブロードフェーズ候補を評価し、どれがオーバーラップするかを定義する。このステップは、ブロードフェーズでフィルタリングされた候補の数に比例する。このステップでは高価な計算を行います。

  4. 反復ソルバーを使って速度と位置の制約を解決します。

  5. 力と速度を統合し、スリーピングボディを検出し、以前のブロードフェーズクエリを解決します。

これらのタスクのほとんどは、エントリー数またはエントリー間の相互作用の量に比例してリニアにスケールします。

したがって、動的エントリーの量を減らす方法は、動かない動的コライダーを静的コライダーに変えることです。

Static Collidersに関する情報は以下を参照してください: 静的コライダー

もう一つの方法は、例えば物理レイヤーやクエリオプションを使って、ボディ間の相互作用を減らすことです。

Collision matrixの3Dと2DはUnityからインポートされ、Simulation Configで利用できます。

layer matrix screenshot

ワールドとバケットサイズ

物理設定の詳細については、以下を参照してください: Settings

World SizeMapData コンポーネントによってベイクされる Map アセットのフィールドです。物理エンジンでプレイ可能なエリアを定義します。 マップは Buckets と呼ばれる一連のセクションに分割されます。これらは、広いフェーズと狭いフェーズのクエリを解決するために使用されます。

World Size

World Sizeは効率的であるために、ゲームのプレイアブルエリアのサイズとできるだけ一致させるべきです。

world size screenshot

最初の画像では、World Sizeがゲームプレイで実際に使用される領域よりも大きい。バケットは等間隔に配置されておらず、無駄になっています。2番目の画像では、オブジェクトはワールドの領域に均等に広がっています。

重要なことは、必要以上にバケットを増やしても性能は上がりませんし、バケットが少なすぎると評価する項目が多くなりすぎるということです。最初のバケットや最後のバケットに多くのエントリがあると、パフォーマンスに大きく影響します。

Task Profiler を参照してパフォーマンスを評価し、あなたのケースに最適な値を調整してください。

注意:ワールドサイズの制限から外れているものは、最初か最後のバケット(近い方)にあるとみなされます。

Bucket Subdivision

Bucket Subdivisionは、通常の物理クエリをより効率的にするために使われます。もしあなたのゲームが通常のクエリを使わない場合、例えばBroad-phase Queriesだけを使う場合、サブディビジョンカウントを0に設定することができます。

そうでない場合は、MapDataコンポーネントで提供されるデフォルト値で十分です。

バケット軸

ワールドサイズのサブディビジョンの軸は、ゲーム内のオブジェクトがどのように分布しているかによって、パフォーマンスを向上させることができます。

bucketing axis screenshot

左の画像では、いくつかのバケットには5つのエントリーがありますが、右の他のバケットには3つしかありません。

そのため、この画像では Bucketing Axis を水平に設定すべきです。なぜなら、物理体がバケットに均等に分散されるからです。

注意: この例では、数個のエントリーしかないので、変化は最小限です。ただし、数百、数千のエントリーにスケールアップした場合は、間違いなく重要になってきます。

Triangle Cell Size

注意:これは3Dゲームにのみ関係します。

Triangle Cell Size は、3D 静的コライダー三角形を分割するセルのサイズを定義します。 ダイナミックエンティティとスタティックメッシュの衝突は、対応するセルと隣接するセルのみで評価されます。

これを最適化するには:

  • セルあたりのトライアングルの数が多すぎないようにする。
  • セルの数が多すぎないようにする。

地形とメッシュのコライダは 物理エンジンのパフォーマンスに重要な役割を果たすので、適度な三角形の密度を維持する必要があります。このため、メッシュによっては、ビューに同じメッシュを使用するのではなく、コライダのために2つ目の簡略化されたメッシュを作成することをお勧めします。

これらを視覚化するには、QuantumEditorSettingsで関連するフィールドを有効にします。

triangle gizmos screenshot

シミュレーション実行の最適化

Quantumの物理エンジンは、多様な機能のために複数のスケジュールされたステップを実行します。しかし、ゲームによってはそのすべてが必要とは限りません。

SimulationConfigアセットで、これらの機能を個別に無効にすることができます:

physics toggle screenshot

休息オブジェクト

ゲーム中に長時間動く必要のないオブジェクトがある場合、それらをスリープ状態にし、力、速度、積分、衝突判定をスキップします。このオプションは SimulationConfig アセットで有効にできます:

sleeping screenshot

ソルバーの反復回数

SimulationConfigアセットのSolver Iterationsフィールドは、衝突や関節などの物理エンジンで使用される制約を解くために使用される反復回数を表します。

デフォルト値は4で、ほとんどの場合はこれで問題ありません。しかし、必要な精度に応じて増減させることができます。

レイキャストの最適化

各フレームで多くのレイキャストが発生する場合、それらが正しく最適化されていることを確認することをお勧めします。

例えば:

  • LayerMaskを追加して、重要でないオブジェクトとの不要な衝突評価を避ける。

  • レイキャストの距離をできるだけ小さくして、不要な衝突評価を避ける。

  • 最初の衝突だけを気にする場合は RaycastAll の代わりに Raycast を使う。

  • Raycastメソッドで QueryOptions を使って、関係ないものにぶつからないようにします。

QueryOptionsの詳細については、以下を参照してください: Queries

ブロードフェーズクエリー

上述したように、broadphaseクエリはゲーム内のクエリを最適化するために使用することができます。詳しくは Broad-phase Queries を参照してください。

Back to top