実行時に NavData を使用する

NavData はゲーム内で実行時に 1 つまたは複数の Database を使用して管理されます。これは同じ物理的寸法および移動モデルを共有するキャラクタの NavData のひとまとまりになったセットを管理する役割を持つオブジェクトです。

このドキュメントの統合チュートリアルを完了している場合(「Navigation をゲーム エンジンに統合する」を参照)、実行時に NavData をロードおよびアンロードするための Database の基本的な使い方は理解しているはずです。このページでは、このセクションのその他のトピックとともに、いくつかの追加の詳細と考慮事項について説明します。

データベースを作成する

World を作成するときは、World がいくつの Database を作成して管理するかを指定する必要があります。詳細は、「統合フェーズ 1c: World を設定する」を参照してください。

Database は、同じ設定パラメータのセットを使用して作成された NavData のみをロードすることができます。物理的寸法または移動能力が異なるために同じ NavData を共有できないキャラクタがある場合、World に複数の Database を設定する必要があります。詳細は、「複数の Database を使用する」を参照してください。

World によって管理される Database の数は、World の作成後に変更することはできません。

メモリに NavData をロードする

地形用のNavDataまたは地形のセクタを Database に追加するには、最初に NavData オブジェクトを作成し、ファイルまたはメモリ バッファからデータを読み込んでオブジェクトにデータを設定して、このオブジェクトを管理する Database で初期化する必要があります。

ファイルからロードする方法を示すコード サンプルについては、「統合フェーズ 3: NavData をロードおよびアンロードする」を参照してください。

メモリ バッファからロードする方法を示すコード サンプルについては、「統合フェーズ 6a: NavData をアセット パイプラインに統合する」を参照してください。

Database 内の NavData を追加および削除する

NavData を Database に追加してパス ファインディング、パス フォローイング、クエリ システムを利用できるようにする場合、またはゲーム内で必要でなくなったときに NavData を Database から削除する場合、即時または非同期の 2 つの方法から選ぶことができます。

即時

NavData を追加および削除するための最も直接的な方法です。NavData クラスの次のメソッドを使用します。

KyResult NavData::AddToDatabaseImmediate();
KyResult NavData::RemoveFromDatabaseImmediate();

この方法を使用すると、Database の完全更新が即座に実行され、呼び出しスレッドは更新が完了するまでブロックされます。この更新の間に、新しいデータは既存の NavData に完全につなぎ合わされるか、他の NavData から完全に分離されます。

この方法には、常に最新の追加または削除によって更新された最新のデータを Bot およびクエリに使用できるという大きなメリットがあります。ただし、この方法では現在のフレームで全体の更新が行われるため、実際のプロダクションで大きなデータセットとともに使用すると CPU のピークが発生することがあります。また、別のスレッドでクエリを実行する場合、クエリが使用しているデータを修正すると予期しない結果またはクラッシュを引き起こす可能性があるため、マルチ スレッディングには注意する必要があります。したがって、この方法は主に初期統合およびプロトタイピング フェーズで使用することが想定されています。ただし、最終的には非同期のデータの追加および削除に移行する場合は例外となります。

ただし、データ生成プロセスの後処理フェーズなどのゲーム ループのコンテキスト外でデータをロードする場合は、この方法を使用しなければならないことに注意してください。

非同期

NavData を安全に追加および削除するには、次のメソッドを使用します。

KyResult NavData::AddToDatabaseAsync();
KyResult NavData::RemoveFromDatabaseAsync();

この方法では、NavData の追加要求または削除要求は登録され、World の更新中に後続のフレームで処理されます。

  • World の更新中に 非同期の Database の更新が開始されると、その World でのその後の Database 内 NavData の追加要求または削除要求は更新が完了するまで処理されません。そのため、非同期追加または削除を要求したときの Database の現在の状態によって、処理が次のフレームに開始される場合や、数フレーム遅延する場合があります。
    注:これは、パフォーマンスを最適にするためには、追加と削除の要求を World ごとにグループ化して同じフレームで一括して要求するよう試みる必要があることも意味します。
  • Database 内のデータの現在の状態によって、さらには関連する計算の複雑さ(考慮する必要がある NavMesh に対する動的な修正を発生させる TagVolume の数など)によって、処理が単一フレームで完了する場合もあれば複数のフレームに渡ってタイム スライスされる場合もあります。
  • 確かなのは、少なくとも 1 フレームが経過するまでは新しいデータのセットが Database に反映されないということです。

Database はデータの追加要求および削除処理の追跡に含まれる複雑なことのすべてを管理します。また、要求のステータスを追跡して、Bot およびクエリが Database 内の NavData セットに対して行った最新の変更を使用しているかどうかを確認する際にも役立つ場合があります。各 NavData オブジェクトは自身のステータスの値を保持しており、NavData::m_databaseStatus からアクセスできます。ここでは、割り当てられた Database 内のその NavData の現在のステータスが示されます。

次のイメージは、これらのステータスの値が追加要求および削除要求に応じてどのように設定されるかを示します。ステータスの値は赤、ユーザが開始したアクションは黒、内部アクションは青で表示されています。

メモリから NavData をアンロードする

Database から NavData オブジェクトを削除した後は常に、削除した NavData オブジェクトに保持しているポインタを KY_NULL に設定する必要があります。これにより、リファレンス カウント メカニズムをデクリメントします。