You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm getting this random crash when UglTFRuntimeAsset::LoadSkeletalMeshRecursiveAsync() is invoked from a lambda running on a background thread (std::thread):
I'm not entirely sure how shall I avoid this? Do I need to check every time for garbage collection before lambda is executed? Seems like a lot of additional checking and code (for postponing lambda execution). There must be some other way of doing it in Unreal maybe?
The text was updated successfully, but these errors were encountered:
peetonn
changed the title
Getting "" when LoadSkeletalMeshRecursiveAsync invoked from background thread.
Getting "Creating UObjects while Collecting Garbage is not allowed!" when LoadSkeletalMeshRecursiveAsync invoked from background thread.
Jul 14, 2022
peetonn
changed the title
Getting "Creating UObjects while Collecting Garbage is not allowed!" when LoadSkeletalMeshRecursiveAsync invoked from background thread.
Getting "Creating UObjects while Collecting Garbage is not allowed!" when LoadSkeletalMeshRecursiveAsync is invoked from background thread.
Jul 14, 2022
Hey. I know this is an old issue, but we also encountered GC problems importing skeletal meshes in our project.
The main problem seems to be that the glTFRuntimeParser gets kicked off to a worker thread when calling the async API, but internally it creates and references various UObjects internally, which is problematic in Unreal. UObjects should only really be handled on the game thread. We worked around this locally in UglTFRuntimeFunctionLibrary::glTFLoadAssetFromFilenameAsync by moving the call to FglTFRuntimeParser::FromFilename back to the game thread, while keeping the task completion async like this:
void UglTFRuntimeFunctionLibrary::glTFLoadAssetFromFilenameAsync(const FString& Filename, const bool bPathRelativeToContent, const FglTFRuntimeConfig& LoaderConfig, const FglTFRuntimeHttpResponse& Completed)
{
UglTFRuntimeAsset* Asset = NewObject<UglTFRuntimeAsset>();
if (!Asset)
{
Completed.ExecuteIfBound(nullptr);
return;
}
Asset->RuntimeContextObject = LoaderConfig.RuntimeContextObject;
Asset->RuntimeContextString = LoaderConfig.RuntimeContextString;
// Annoying copy, but we do not want to remove the const
FglTFRuntimeConfig OverrideConfig = LoaderConfig;
if (bPathRelativeToContent)
{
OverrideConfig.bSearchContentDir = true;
}
// The parser is currently creating and referencing various UObjects, so it may not run on a worker thread,
// or it will interfere with the GC. See also related open Github issue: https://github.com/rdeioris/glTFRuntime/issues/39
TSharedPtr<FglTFRuntimeParser> Parser = FglTFRuntimeParser::FromFilename(Filename, OverrideConfig);
Async(EAsyncExecution::Thread, [Parser, Asset, Completed]()
{
FGraphEventRef Task = FFunctionGraphTask::CreateAndDispatchWhenReady([Parser, Asset, Completed]()
{
if (Parser.IsValid() && Asset->SetParser(Parser.ToSharedRef()))
{
Completed.ExecuteIfBound(Asset);
}
else
{
Completed.ExecuteIfBound(nullptr);
}
}, TStatId(), nullptr, ENamedThreads::GameThread);
FTaskGraphInterface::Get().WaitUntilTaskCompletes(Task);
});
}
I'm getting this random crash when
UglTFRuntimeAsset::LoadSkeletalMeshRecursiveAsync()
is invoked from a lambda running on a background thread (std::thread
):I'm not entirely sure how shall I avoid this? Do I need to check every time for garbage collection before lambda is executed? Seems like a lot of additional checking and code (for postponing lambda execution). There must be some other way of doing it in Unreal maybe?
The text was updated successfully, but these errors were encountered: