UnrealEngineのDatasmithRuntimeで初回3Dモデルのロードができない現象があった調査して対応しました。
一応、UnrealEngineにバグ報告とpullreqはしてみた(やり方がまずいのか反応なし)のですがその内容についてまとめておきます。
確認した環境
UE4.27.2
UE5.0.3
発生する現象
CollabViewerでも発生しますがDatasmithRuntimeでランタイム中に3DモデルをADatasmithRuntime::LoadFile()を使ってロードしようとすると初回だけロードできない現象がありました。
原因
初回ロード時にFTranslationThread::ThreadEventが非同期に設定されますが、設定される前にFTranslationThread::AddJob()が実行され、その中でまだnullptrであるThreadEventがジョブに設定されてしまっています。
ジョブがキューから呼び出されて実行される際にThreadEventがnullptrかどうかチェックされ、nullptrの場合はロード処理を終了しています。
調査方法
以下の行の前でログを出すと初回ロード時にThreadEventがnullptrです。
https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/DatasmithRuntime.cpp#L359
以下の行の後にログを出すと2、1の順で出力されます(ジョブへのThreadEvent設定の後に、ThreadEventに値が設定されています)。
- https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/DatasmithRuntime.cpp#L341
- https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Public/DatasmithRuntime.h#L82
対応方法
以下のようにDatasmithRuntimeプラグインのEngine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/DatasmithRuntime.cppを修正します。
DatasmithRuntimeプラグインを自プロジェクトに配置するとUnrealEngine全体をソースコードからビルドせずに修正できます。
bool ADatasmithRuntimeActor::LoadFile(const FString& FilePath)
{
...
[&, FilePath]() -> void // <= FilePath追加
{
FPlatformProcess::SetThreadName(TEXT("RuntimeTranslation"));
TranslationThread->bKeepRunning = true;
TranslationThread->ThreadEvent = FPlatformProcess::GetSynchEventFromPool();
TranslationThread->AddJob({ this, FilePath }); // <= 追加
TranslationThread->Run();
}
);
}
else // <= 追加
{ // <= 追加
TranslationThread->AddJob({ this, FilePath });
} // <= 追加
// Set all import options to defaults for DatasmithRuntime
return true;