This document is about: QUANTUM 2
SWITCH TO

Navmeshリージョンを使用する

Quantumにおける決定性ロールバックのパフォーマンス要件を尊重する一方、navmeshリージョンはUnitys dynamic navmesh carvingの妥協案となっています。これらを使用して、事前に定義しておいたnavmeshのエリアを動的に、最小限のパフォーマンスオーバーヘッドでトグルすることができます。

リージョンはマスクとしてトライアングルの内側にエンコードされているため(unsigned long)、マップごとのさまざまなリージョンIDの最大数は64となります(Navigation.Constants.MaxRegions)。別のリージョンに同じIDを再度使用することも可能です。

主なQuantum navmesh (Walkable)は、リージョンではなく、トグルすることはできません。

ステップ 1) Quantum Regions piggy-back on the Unity navmesh areas. 新しいエリアを作成します。以下の画像ではToggleableという名前を選択していますが、どのような名前でも構いません。

隣同士にトグル可能なリージョンがある場合検出されるようにするには、異なるエリアIDを使用する必要があります。その場合、こちらで複数のエリアを作成します。

Region Areas

ステップ 2) MapNavMeshUnityに新しいエリアを追加します。これを行わないと、ベイキングがどのエリアを検出すべきが把握できません。

Add Region Area

ステップ 3) UnityはMeshRendererオブジェクトを使用してnavmeshにエリアを投影します。MeshRendererを使用してGameObjectを作成し、MapNavMeshRegionをアタッチします。

Region Setup

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で表示します。

Active Regions

ステップ 5) コード内でリージョンをオフに切り替え、エージェントがこれを回避するのを確認します。

C#

public override void OnInit(Frame f) {
    var regionId = f.Map.RegionMap["foo"];
    f.NavMeshRegionMask->ToggleRegion(regionId, false);
}
Inactive Regions

ステップ 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であり、オフに切り替えられないマスクがゼロか確認します。
Back to top