【UE5】LoadObjectとConstrcutorHelperについて
はじめに
今回からUnreal Engine5で私個人が気づいたことについて書き留めていきたいと思っています。
今回の議題
-
LoadObjectとConstructorHelperについての違い
-
LoadObjectの罠について
ConstrcutorHelperとLoadObjectは、ともにコンテンツドロワーのアセット(音楽、画像、Mesh、Particleなど)から読み込む機能を持っています。
どちらもUStaticMesh*などをロードするとMaterialまで一緒にロードされてきます。このことをハード参照
#include "UObject/ConstructorHelpers.h"
使い方(一例)
ConstrctuorHelpers
ThirdPersonTempleteのGameMode内でも見かけますよね(あれは、FClassFinderですが)
使用できる場所:Constrcutor内のみ
#include "UObject/ConstrcutorHelpers.h"
AHoge::AHoge()
{
ConstructorHelpers::FObjectFinder<UMaterialInstance> MaterialFinder(TEXT("ファイルのリファレンスパス"));
if(MaterialFinder.Succeeded()) // うまくロード出来たら
{
UMaterialInstance* material = MaterialFinder.Object;
}
}
LoadObject
使用できる場所:どこでも使えそう(ここでの突込みはNGで...)
void AHoge::BeginPlay()
{
Super::BeginPlay();
// アセットをロードする
UParticleSystem* Particle = LoadObject<UParticleSystem>(nullptr,TEXT("アセットのリファレンスパス"));
if(Particle != nullptr)
{
// パーティクルの発生
UNiagaraFunctionLibrary::SpawnSystemAtLocation(GetWorld(),Particle,GetActorLocation());
}
間違いの例
私は、LoadObjectはConstrcutorHelperの強化版だと思い込んでいました.
どこでもLoadObjectは使えると思い込んでました....
そこで以下のように記載しました...
Ahoge::Ahoge()
{
// 前略中略後略省略
UStaticMesh* Mesh = LoadObject<UStaticMesh>(nullptr, TEXT("/Script/Engine.StaticMesh'/Game/StarterContent/Shapes/Shape_Cube.Shape_Cube'"));
if (Mesh != nullptr)
{
ObstacleMesh->SetStaticMesh(Mesh);
}
// 省略
}
そこで、Constrcutor内ででも書くのが面倒だからという理由で、LoadObject関数を主に使用していたら...クラッシュが!
前までは気にしていなかったのですが、何が起こっているのかCrashReporterを(本来ならLogも確認するべきでしょうが頭にありませんでした)見ていると、IsInGameThread()でアサーションエラー(意図的に出しているエラー?)
Assertion failed: IsInGameThread() [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Engine\Private\StaticMeshCompiler.cpp] [Line: 371]
調べてみたところ、LoadObject関数は、コンストラクタ内では使用してなイケナイとのこと。ルール違反みたいでした...
Constrcutor内では素直にConstructorHelperさんを頼ったほうがよさそうな気がします...
ConstructorHelpers::FObjectFinder<UStaticMesh> ObstacleMeshFinder(TEXT("/Script/Engine.StaticMesh'/Game/StarterContent/Shapes/Shape_Cube.Shape_Cube'"));
if (ObstacleMeshFinder.Succeeded())
{
// staticMeshを設定する
ObstacleMesh->SetStaticMesh(ObstacleMeshFinder.Object);
}
最後に
ConstrcutorとLoadObjectをきっかけにハード参照、ソフト参照のことが知れてとても勉強になりました。
次は、ソフト参照(TSubclassOf<クラス名>(TSoftObjectPath(*Path)).LoadSynchronous();についても考えられればと思います。
参考になる文献
- Epic,Unreal Engine アセットの参照,最終確認日:2025年8月22日
- 平野,【UE4】ハード参照とソフト参照について,Logialbeat,最終確認日:2025年8月22日
Discussion