🏔️

[UE] サブレベルでナビメッシュを持つには

2023/08/10に公開

(UE5.1、UE4.27で確認)

やりたいこと

「ゲームを通してパーシスタントレベルを固定し、サブレベルを読み替えることでマップ遷移を行う」レベル構成だとする。

PLv_GameMain
├ SLv_Test01_Map (地形データ)
├ SLv_Test01_Ev (イベントアクタ)
├ ...
SLv_Test01_Nav (ナビメッシュデータ)

で、上記のように、各マップのナビゲーションメッシュをサブレベルに持たせたいケースを考える。

問題

素直に以下のようにアクタ配置するだけだとうまくいかない。

SLv_Test01_Nav
├ NavMeshBoundsVolume
└ RecastNavMesh-Default

以下のような(古い)情報によると、(昔の)UEでは、ナビメッシュボリュームはパーシスタントレベルに配置されていることが前提になっているらしい。
(つまり、サブレベルに配置したナビメッシュは反映されない)
https://forums.unrealengine.com/t/worldcomposition/455587

だめだったこと

  • パーシスタントレベルにdynamicのナビメッシュボリュームを置く

サブレベルを好きに読み替えても適宜ナビメッシュがランタイム生成されるようになるが(=最強)、さすがに重くて実用的ではないだろう。
ナビメッシュの設定は基本的にはstatic、またはdynamic modifiers onlyで使いたい。ので却下

  • パーシスタントレベルにダミーのナビメッシュを置き、サブレベルに実際に反映したいナビメッシュを置く

うまくいくかと思えたが、更新が反映されない、パスをビルドすると突然ナビメッシュが消失する、など挙動が不安定だった。
運用でカバーどころではない謎挙動

解決策

ふとプロジェクト設定をを眺めていたら、クリティカルなコンフィグがあった。

ナビゲーションシステム_プロジェクト設定
プロジェクト設定 - エンジン - ナビゲーションシステム

サブレベルナビゲーションデータを破棄
(Should Discard Sub Level Nav Data)
trueの場合、ロードされたサブレベル内のナビゲーションデータをゲームで無視します

お前……存在したのか……!

なんでデフォでTrueなん;;

ということで、こちらのチェックボックスを外すことで、フツーにサブレベルでナビゲーションメッシュを取り扱えるようになった。
パーシスタントレベルのダミーも不要。パスをビルドしても消失しない。
解決。

あと

ナビメッシュの設定アクタ(RecastNavMesh-Default)は、NavMeshBoundsVolumeを置いたときに、そのときのパーシスタントレベルに配置される。
そのため、「ナビメッシュ用サブレベルにナビメッシュボリュームを置く際は、ナビメッシュ用サブレベルをパーシスタントレベルにする」必要がある。(多分)

そのため、ナビメッシュ用サブレベルは編集用に以下のレベル構成にしておくと良いと思う。

SLv_Test01_Nav
├ SLv_Test01_Map (地形データ)
├ SLv_Test01_Ev (イベントアクタ)
├ ...

これは何?

同じく上述のプロジェクト設定に、以下の設定項目がある。

ナビゲーションの境界レベルでナビゲーションデータをスポーン
(Spawn Nav Data in Nav Bounds Level)
trueの場合、ナビゲーションの境界があるサブレベルでナビゲーションデータインスタンスのスポーンを試み、falseの場合、パーシスタントレベルでスポーンします

これをTrueにすれば↑のRecast(略)問題が解決するかと思ったけど、特に影響はなさそうだった。

Discussion