NavData 生成システムは、入力ジオメトリに指定するすべてのトライアングルを常に受け付けて考慮します。これにより、実行時にキャラクタに対してアクセス可能となることを意図していない領域で、NavData が生成されることがよくあります。たとえば、屋根の上、木の上、閉ざされた建物内などです。
この余分なデータは、到達できないこれらの領域へのパスを Bot にプランさせようとしない限り、パフォーマンス上問題とはなりません。ただし、他の目的に使用する必要がある追加のメモリがいくらか使用されます。
こうした不要なデータを除外するために利用できるいくつかの異なる手法について、次のセクションで説明します。これらの手法は排他的ではなく、地形のさまざまなレベルまたは領域で最適なプロセスを使用することができます。
NavData 生成システムには、各セクタ用に任意の数のシード ポイントを指定でき、それによって地形の歩行可能エリアを識別できます。1 つのセクタに対して 1 つまたは複数のシード ポイントを指定すると、後処理フェーズは各シード ポイントから NavMesh を通じて伝達されます。これらのシード ポイントから到達可能な領域をカバーする NavMesh のみが保存されます。その他の NavData はすべて破棄されます。
たとえば、次の地形について考えます。デフォルトでは、NavData の分離された領域はすべての屋根の上と各建物内に作成されます(ただし、内部の NavData はイメージには表示されず、実行時に多くのメモリを占有します)。
単一のシード ポイントを地面の任意の位置に配置すると、地面からアクセス可能でないすべての NavData は自動的に破棄されます。これには、下に示すとおり、すべての屋根と建物内部が含まれます。
Navigation Lab でシード ポイントを作成するには、任意の地形上を右クリックし、コンテキスト メニューから Generation > Spawn Seed Point を選択します。
各セクタを作成するときは、セクタに対して作成した設定で GeneratorSectorConfig::AddSeedPoint() メソッドまたは GeneratorSectorConfig::AddSeedPointInClientCoordinates() メソッドを呼び出して、セクタにシード ポイントを提供することができます。
または、ClientInputConsumer::ConsumeSeedPoint() を呼び出して GeneratorInputProducer クラスでシード ポイントを提供することもできます。
各セクタは、セクタの設定でシード ポイントが指定されている場合、またはセクタのトライアングルを取得するために GeneratorInputProducer が呼び出された場合にのみシード ポイントを考慮することに注意してください。そのため、
NavData 生成システムには、不要な領域を囲む 3D ボリュームを指定し、そのボリュームに歩行不可能としてフラグを付けることができます。それらのボリューム内にある入力トライアングルに対して NavData は生成されません。
このサンプルでは、地形の右側にあるキャンプを、プレーヤーが敵意のある NPC からの攻撃を恐れることなく休憩できる場所であるセーフ ゾーンに入れます。
これを行うには、セーフ領域を囲む TagVolume を作成し、"除外" としてフラグを付けます。生成後に、NavMesh は境界で塞がれ、NPC はこの領域に入れなくなります。
Navigation Lab で TagVolume を作成するには:
Generator の TagVolume を作成するには:
各セクタを作成する際に、セクタに対して作成した設定の GeneratorSectorConfig::AddTagVolume() メソッドを呼び出すことで、セクタに TagVolume を提供することができます。
または、ClientInputConsumer::ConsumeTagVolume() を呼び出して GeneratorInputProducer クラスで TagVolume を提供することもできます。
各セクタは、セクタの設定で TagVolume が指定されている場合、またはセクタのトライアングルを取得するために GeneratorInputProducer が呼び出された場合にのみ TagVolume を考慮することに注意してください。そのため、
NavData 生成フレームワークの API を直接使用する場合は、特殊な NavData を使用して除外する領域で、個別の入力トライアングルにタグを付けることができます。生成プロセスの間に、この地形タイプでタグ付けされたトライアングルのみを持つピクセルに対しては、NavData は生成されず、NPC はこれらの領域で移動できなくなります。
この手法を使用するには、GeneratorInputProducer のカスタム クラスは ClientInputConsumer::ConsumeTriangle() または ClientInputConsumer::ConsumeTriangleFromPosInClientCoordinates() メソッドを使用して、各入力トライアングルを ClientInputConsumer に提供する必要があります。DynamicNavTag::SetAsExclusive() メソッドを呼び出して、これらのメソッドに引数リストで提供する DynamicNavTag を除外として設定します。
これらのトライアングルは、必要に応じて静的な障害物として引き続き考慮されるようにするため、生成システムに渡すときは、単にトライアングルを省略するのではなく、この地形タイプ メカニズムを使用することをお勧めします。
NavMesh の任意の部分について、最小サーフェス領域を設定できます。NavData を生成した後に、後処理フェーズでこのしきい値より小さいサーフェス領域を持つ NavFloor が破棄されます。
この設定は、NavMesh がお互いに接続されていない、分離された多くの小さい領域があり、キャラクタが横断しないようにする場合に役立ちます。
隣接するセクタで NavData との一貫性を保証するため、隣接するセクタと重なり合う部分に接触する NavMesh のすべての領域が常に保持されます。したがって、2 つの隣接するセクタの間の境界上に小さい屋根がある場合、意図したとおりにフィルタされない可能性があります。
このテスト地形では、スロープ上の地形のローカルなバリエーションは、実行時にキャラクタが決して移動する必要がない、いくつかの小さい接続していない領域となります。
最小サーフェス領域のしきい値を上げると、周囲の NavData の特性に影響を与えることなく、それらの小さい領域内にある NavData をすべて自動的に破棄できます。
最小サーフェス領域パラメータを使用して通常はフィルタされるサーフェス上にシード ポイントがある場合、シード ポイントを含むサーフェスは、ノイズとして認識されるのに十分小さい場合、すなわち GeneratorAdvancedParameters::m_noiseReductionSurface パラメータより小さい場合を除き、維持されます。以下を参照してください。
Navigation Lab で最小サーフェスを設定するには:
サーフェス領域のしきい値は、GeneratorInputOutput.m_params.m_advancedParameters を通じてアクセス可能な GeneratorAdvancedParameters::m_minNavigableSurface メンバーの値で設定できます。
上記の GeneratorAdvancedParameters::m_minNavigableSurface パラメータの他に、GeneratorAdvancedParameters::m_noiseReductionSurface パラメータがノイズ リダクションをコントロールするために使用されています。後者のパラメータの効果は似ていますが、次の点が異なります。
ほとんどのプロジェクトでは、GeneratorAdvancedParameters::m_minNavigableSurface パラメータを調整して GeneratorAdvancedParameters::m_noiseReductionSurface パラメータはデフォルトの値のままにすることをお勧めします。ただし、パフォーマンスを最適化し一貫性を保つために GeneratorAdvancedParameters::m_noiseReductionSurface の値は通常 GeneratorAdvancedParameters::m_minNavigableSurface の値よりも小さくなるように保つため、GeneratorAdvancedParameters::m_minNavigableSurface を非常に小さい値に設定する場合は、値を手動で小さくする必要がある場合があります。