2023/08/31_UE5.1_問題:非同期でAnyBackgroundThreadNormalTaskを使いローディングスクリーンを出そうとするとクラッシュ
問題
非同期でAnyBackgroundThreadNormalTaskを使いローディングスクリーンを出そうとするとクラッシュした。
コード
#include "Async/TaskGraphInterfaces.h"
void ULoadingScreenUserWidget::BeginLoadingScreen(ULoadingScreenUserWidget* LoadingWidget)
{
UE_LOG(LogTemp, Log, TEXT("ULoadingScreenUserWidget::BeginLoadingScreenVer1.3:AnyBackgroundThreadNormalTask"));
// このラムダ式内が別スレッド処理
// バックグラウンドスレッドで非同期タスクを作成し実行
//ラムダ式内で使用する変数にはキャプチャモードを指定する必要があります>LoadingWidget。
FFunctionGraphTask::CreateAndDispatchWhenReady([this, LoadingWidget]()
{
処理
}, TStatId(), NULL, ENamedThreads::AnyBackgroundThreadNormalTask);// バックグラウンドスレッドによる非同期タスクの実行
}
解決
バックグラウンドスレッドだとSlateにアクセスすることは許可されていないらしい。
AnyBackgroundThreadNormalTaskをGameThreadに変更してクラッシュしなくなった。
}, TStatId(), NULL, ENamedThreads::AnyBackgroundThreadNormalTask);
↓
}, TStatId(), NULL, ENamedThreads::GameThread);
クラッシュメッセージ
LoginId:aa1f1bbf4535f59af29e15b40c3e0dba
EpicAccountId:b47207a1bd2448a8833bb07151bfe2a6
Assertion failed: IsInGameThread() || IsInSlateThread() [File:D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp] [Line: 1225] Slate can only be accessed from the GameThread or the SlateLoadingThread!
UnrealEditor_SlateCore!SWidget::Invalidate() [D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SWidget.cpp:1225]
UnrealEditor_SlateCore!FSlateAttributeMetaData::InvalidateWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Private\Types\SlateAttributeMetaData.cpp:369]
UnrealEditor_SlateCore!SlateAttributePrivate::TSlateAttributeBase<SWidget,EVisibility,SlateAttributePrivate::FSlateAttributeNoInvalidationReason,TSlateAttributeComparePredicate<TEqualTo<void> >,0>::Assign() [D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Public\Types\Attributes\SlateAttributeBase.inl:384]
UnrealEditor_SlateCore!SLeafWidget::SetVisibility() [D:\build\++UE5\Sync\Engine\Source\Runtime\SlateCore\Private\Widgets\SLeafWidget.cpp:11]
UnrealEditor_UMG!UWidget::SynchronizeProperties() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:1359]
UnrealEditor_UMG!UImage::SynchronizeProperties() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Image.cpp:46]
UnrealEditor_UMG!UWidget::TakeWidget_Private() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:995]
UnrealEditor_UMG!UWidget::TakeWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:916]
UnrealEditor_UMG!UCanvasPanelSlot::BuildSlot() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\CanvasPanelSlot.cpp:33]
UnrealEditor_UMG!UCanvasPanel::RebuildWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\CanvasPanel.cpp:59]
UnrealEditor_UMG!UWidget::TakeWidget_Private() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:929]
UnrealEditor_UMG!UWidget::TakeWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:916]
UnrealEditor_UMG!UUserWidget::RebuildWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\UserWidget.cpp:776]
UnrealEditor_UMG!UWidget::TakeWidget_Private() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:929]
UnrealEditor_UMG!UWidget::TakeWidget() [D:\build\++UE5\Sync\Engine\Source\Runtime\UMG\Private\Components\Widget.cpp:916]
UnrealEditor_AsyncLevelLoad!<lambda_52bd4afc06b761b81e29596b35277b24>::operator()() [C:\Users\roy00\OneDrive\Documents\Unreal Projects\PluginTest5_1\Plugins\AsyncLevelLoad\Source\AsyncLevelLoad\Private\LoadingScreenUserWidget.cpp:19]
UnrealEditor_AsyncLevelLoad!TGraphTask<TFunctionGraphTaskImpl<void __cdecl(void),0> >::ExecuteTask() [C:\Program Files\Epic Games\UE_5.1\Engine\Source\Runtime\Core\Public\Async\TaskGraphInterfaces.h:1348]
UnrealEditor_Core!<lambda_13c427d0bfcf321a066cb5a2badfbc27>::operator()() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp:2051]
UnrealEditor_Core!LowLevelTasks::TTaskDelegate<LowLevelTasks::FTask * __cdecl(bool),48>::TTaskDelegateImpl<<lambda_17c904c32264d0348d15245fba0e1bff>,0>::CallAndMove() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\Fundamental\TaskDelegate.h:171]
UnrealEditor_Core!LowLevelTasks::FTask::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Async\Fundamental\Task.h:656]
UnrealEditor_Core!LowLevelTasks::FScheduler::ExecuteTask() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\Fundamental\Scheduler.cpp:184]
UnrealEditor_Core!LowLevelTasks::FScheduler::TryExecuteTaskFrom<&LowLevelTasks::TLocalQueueRegistry<1024>::TLocalQueue::DequeueGlobal,0>() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\Fundamental\Scheduler.cpp:361]
UnrealEditor_Core!LowLevelTasks::FScheduler::WorkerMain() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Async\Fundamental\Scheduler.cpp:402]
UnrealEditor_Core!UE::Core::Private::Function::TFunctionRefCaller<<lambda_0a548c7e497de3cc77a9e48080e1524f>,void __cdecl(void)>::Call() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Public\Templates\Function.h:475]
UnrealEditor_Core!FThreadImpl::Run() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\HAL\Thread.cpp:67]
UnrealEditor_Core!FRunnableThreadWin::Run() [D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\Windows\WindowsRunnableThread.cpp:149]
ChatGPT
このエラーメッセージは、Slate(Unreal Engine のUIフレームワーク)のウィジェットにアクセスする際に、UIの操作はメインスレッドまたはSlateスレッドからのみ許可されているため、それ以外のスレッドからアクセスしようとしたときに発生します。SlateはUIを描画するためのスレッドセーフな仕組みを持っており、特定のスレッドからしか操作できないように制御されています。
具体的には、このエラーメッセージに示されている場所から始まり、スタックトレースを通じてコールバックチェーンを辿ることで、問題がどこで発生しているかを特定できます。
このエラーメッセージの原因は、非同期ロード中に別スレッドからUIの操作(特にSlateウィジェットの操作)を試みていることです。非同期ロードのタスクはバックグラウンドスレッドで実行されるため、Slateにアクセスすることは許可されていません。
このエラーを解決するためには、非同期ロード中にUI操作を行わず、ロード完了後にUIを更新するようにするか、非同期ロードタスク内でUI操作が必要な場合には適切なメカニズムを使用してUI操作をメインスレッドに戻す必要があります。ただし、UI操作のスレッドセーフな処理に注意する必要があります。