お世話になっております。
弊社ではほぼ空のパーシスタントレベルにいくつかの場所のサブレベルを読み替えながらゲームを実行しているのですが、
(建物の廊下から部屋に入ってまた廊下に出てくる…のような感じです)
今のサブレベルのUNLOAD->次のレベルのLOADを繰り返しているとPC版で低い確率ですがアサートが出ます(PS5やXBOXでは問題ありません)。
Developビルドですが、エディターかパッケージかでソースの行数が若干が異なり、以下になります。
・エディター
Assertion failed: CaptureIndex < Scene->ReflectionSceneData.CubemapArray.GetMaxCubemaps() [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Renderer\Private\ReflectionEnvironmentCapture.cpp] [Line: 1148]
ブレークポイント命令 (__debugbreak() ステートメントまたは類似の呼び出し) が UnrealEditor.exe で実行されました。
・パッケージ
Ensure condition failed: CaptureSceneStatePtr [File:ReflectionEnvironmentCapture.cpp] [Line: 1476] Reflection capture /Game/mygame/Maps/BG1_lit.BG1_lit:PersistentLevel.BoxReflectionCapture_1.NewReflectionComponent uploaded twice without reloading its lighting scenario level. The Lighting scenario level must be loaded once for each time the reflection capture is uploaded.
パッケージは確率が低い(10~20人でプレイして二日に一回ぐらい)ので確率の高いエディター(30分ぐらいで起こせます)で検証しているのですが、一応サードパーソンで再現プロジェクトを作ることができました。
アサートするときはFSceneの反射キャプチャデータの配列で不整合が起こっているようで、何となくスレッドセーフになっていないような感じがしております。
またUNLOAD後にFSceneInterfaceのResetReflectionCaptures()を呼び出すとアサートが起こらなくなるのは確認できています。
そこで質問なのですが、UNLOADの完了を安全に待つにはどうすれば良いでしょうか?サンプルではGetLevelStreamingStatus()で待っているのですが、他にも追加で何か必要でしょうか?
*LevelStreaming.cppに以下のようなコメントがあり、LEVEL_UnloadedButStillAround状態が取れていないようではあります
// We can’t use FindObjectFast() while the GC is running… Let’s treat the level as unloaded at this point.
また仮に安全に待つ方法がない場合、製品版でもResetReflectionCaptures()を使って大丈夫でしょうか?
SceneInterface.hに以下のコメントがあり、エディターでの使用を想定しているような感じもあります。
// instead of needing to restart the editor
他に試してみた事として、UNLOADを待つときに1秒のウェイトを入れてもほぼ同じ確率でアサートしますが、5秒のウェイトを入れるとかなり確率が下がりますが、やはりたまにアサートが出ます。
また以下のUDNの投稿の内容が割と近い感じがしております。
[Content removed]
エンジン改造でそれぞれの関数にUE_LOG()を追加したところ、そちらに出てくるOnRegisterとCaptureOrUploadReflectionCaptureの順番が逆になる現象が弊社ゲームでも起こっているようでした。
以上、お手数おかけしますがよろしくお願い致します。
*アサートで止まっているのでCrashesフォルダは無いようでした。VSの画像を添付します
[Attachment Removed]