Navmeshリージョンを使用する
Quantumにおける決定性ロールバックのパフォーマンス要件を尊重する一方、navmeshリージョンはUnitys dynamic navmesh carvingの妥協案となっています。これらを使用して、事前に定義しておいたnavmeshのエリアを動的に、最小限のパフォーマンスオーバーヘッドでトグルすることができます。
リージョンはマスクとしてトライアングルの内側にエンコードされているため(unsigned long)、マップごとのさまざまなリージョンIDの最大数は64となります(Navigation.Constants.MaxRegions)。別のリージョンに同じIDを再度使用することも可能です。
主なQuantum navmesh (Walkable)は、リージョンではなく、トグルすることはできません。
Navmesh Regionsを作成する
ステップ 1) Quantum Regions piggy-back on the Unity navmesh areas. 新しいエリアを作成します。以下の画像ではToggleableという名前を選択していますが、どのような名前でも構いません。
隣同士にトグル可能なリージョンがある場合検出されるようにするには、異なるエリアIDを使用する必要があります。その場合、こちらで複数のエリアを作成します。
ステップ 2) MapNavMeshUnityに新しいエリアを追加します。これを行わないと、ベイキングがどのエリアを検出すべきが把握できません。
ステップ 3) UnityはMeshRendererオブジェクトを使用してnavmeshにエリアを投影します。MeshRendererを使用してGameObjectを作成し、MapNavMeshRegionをアタッチします。
Idは、コードからMap.RegionMapを通してアクセス可能な一意の文字列です。Map.RegionMapからは後でリージョンIDを取得するとこができます(int, flag)。
CastRegionは CastRegionに設定する必要があります。スクリプトは例として、navmeshにリージョンを投影する必要のないOff Mesh Linksに再利用されます。
NavMeshHelperでは、正しくGameObjectが設定されているかダブルチェックを行うことができます。例えば、staticに設定されているか、選択されているエリアが自分たちのリージョンエリアであるかどうかなどです。
navmeshサーフェスがインストールされている場合、インスペクターの表示は若干異なります。例えばnavmeshエリアを設定するには、NavMeshModifierスクリプトを追加する必要があります。
リージョンインポートの間、トライアングルの元のリージョンスクリプトへのマッチを試み、そのためにメッシュの境界ボックスを使用します。
生成されたトライアングルは100%正確ではないため、MapNavMeshUnityの設定には、フィッティング中にルームを少し追加するRegionDetectionMargin設定があります。
リージョンがエキスポートされていない場合はこの値を増やします。ただし、この値が大きくなりすぎている場合は隣り合うリージョンに問題がある可能性があります。
リージョンを生成するMeshRendererはベイキングの間のみアクティブにしておく必要があります。こちらについてツールを追加したいと思います。
ステップ 4) マップをベイクしてトライアングルの色のついたエリアをリージョンが配置されたnavmeshで表示します。
ステップ 5) コード内でリージョンをオフに切り替え、エージェントがこれを回避するのを確認します。
C#
public override void OnInit(Frame f) {
var regionId = f.Map.RegionMap["foo"];
f.NavMeshRegionMask->ToggleRegion(regionId, false);
}
ステップ 6) リージョンアクティベーションがアクセス可能になり、フレーム内に保管されます。
新しいマップをロードする場合、マスクをリセットする必要があります。ISignalOnMapChangedシグナルの間などは、FrameBase.ClearAllNavMeshRegions()を実行します。
C#
public class ResetRegionsSystem : SystemSignalsOnly, ISignalOnMapChanged {
public void OnMapChanged(Frame f, AssetRefMap previousMap) {
f.ClearAllNavMeshRegions();
}
}
NavMeshRegionMaskオブジェクトのAPIを確認します。以下は概略です。:
NavMeshRegionMask.Defaultは、すべてのリージョンを有効にします。(1に設定)NavMeshRegionMask.ToggleRegion(int region, bool enabled)は、リージョンIDでリージョンを切り替えます。リージョンIDはビットシフトのオフセットで、Map.RegionMapディクショナリを使用、名前で取得できます。NavMeshRegionMask.IsRegionEnabled(int region)は、リージョンがアクティブであるかどうかチェックします。NavMeshRegionMask.IsSubset(NavMeshRegionMask)は、1つのマスクでアクティブになっているリージョンがすべて、他のマスクでも有効化されているか確認するのに使用します。NavMeshRegionMask.Clear()は、すべてのリージョンをアクティブに設定します。NavMeshRegionMask.HasValidRegionsは、マスクに1つ有効オなリージョン設定をされている場合にtrueを返します。NavMeshRegionMask.IsMainAreaは、メインのnavmeshエリアに属するトライアングルに対してtrueであり、オフに切り替えられないマスクがゼロか確認します。