(UE5.1、UE4.27で確認)
やりたいこと
「ゲームを通してパーシスタントレベルを固定し、サブレベルを読み替えることでマップ遷移を行う」レベル構成だとする。
例えば:
PLv_GameMain ←常駐
├ SLv_Test01_Map (地形データ) ←マップ遷移ごとにロード/破棄する(以下同)
├ SLv_Test01_Ev (イベントアクタ)
├ ...
└ SLv_Test01_Nav (ナビメッシュデータ)
というように、各マップのナビゲーションメッシュをサブレベルとして用意したいケースを考える。
問題
上記のレベル構成で、以下のように素直にアクタ配置するだけだとうまくいかなかった。
SLv_Test01_Nav
├ NavMeshBoundsVolume
└ RecastNavMesh-Default
調べると、(※結果的に、昔の)UEではナビメッシュボリュームはパーシスタントレベルに配置されていることが前提になっているとのことだった。
(つまり、サブレベルに配置したナビメッシュは反映されない)
対策として、
- パーシスタントレベルにdynamicボリュームを置く →さすがに高負荷
- パーシスタントレベルにダミーのボリュームを置くと、サブレベルのナビメッシュボリュームも読み込まれる →挙動が不安定だった
あたりで、うまくいかない……と思っていたところ、どうやらそもそも古い情報だったのか、以下の解決法が存在した。
解決策
ふとプロジェクト設定を眺めていたら、クリティカルなコンフィグがあった。
プロジェクト設定 - エンジン - ナビゲーションシステム
サブレベルナビゲーションデータを破棄
(Should Discard Sub Level Nav Data)
「trueの場合、ロードされたサブレベル内のナビゲーションデータをゲームで無視します」
なんでデフォでtrueなん;;
ということで、こちらのチェックボックスを外すことで、フツーにサブレベルでナビゲーションメッシュを取り扱えるようになった。
その他の構成
ナビメッシュの設定アクタであるRecastNavMesh-Defaultは、NavMeshBoundsVolumeを置くとそのときのパーシスタントレベルに自動生成される。
そのため、「ナビメッシュ用サブレベルにRecast(略)を置くには、ナビメッシュ用サブレベルを(編集時に)パーシスタントレベルにする」必要がある。(多分)
ということで、Navサブレベルはエディタ上で以下のレベル構成にしておき、レベル更新時はこのレベルを開いてナビメッシュを生成するようにすると良さそう。
SLv_Test01_Nav
├ SLv_Test01_Map (地形データ)
├ SLv_Test01_Ev (イベントアクタ)
├ ...
これは何?
同じく上述のプロジェクト設定に、以下の設定項目がある。
ナビゲーションの境界レベルでナビゲーションデータをスポーン
(Spawn Nav Data in Nav Bounds Level)
「trueの場合、ナビゲーションの境界があるサブレベルでナビゲーションデータインスタンスのスポーンを試み、falseの場合、パーシスタントレベルでスポーンします」
※デフォルトでfalse
これをtrueにすれば↑のRecast(略)問題が解決するかと思ったけど、特に影響はなさそうだった。
ランタイムのナビメッシュデータインスタンスがどこに生成されるかの設定?
だとしたらナビデータはサブレベルと一緒に破棄されてほしいので、trueにしておくべきか。(要確認)