Massive crash using FObjectFinder. Did I do something massively wrong?

So I have these lines in the code of a class derived from an actor:

void ALevelLayout::ResizeLevel()
{
	Width = FMath::Clamp(Width, 0, 16383);
	Height = FMath::Clamp(Height, 0, 16383);

	// find mesh
	ConstructorHelpers::FObjectFinder<AStaticMeshActor> StaticMesh(TEXT("StaticMesh'LevelLayout'"));
	if (StaticMesh.Succeeded())
	{
		float sx = Width / 100.0f;
		float sy = Height / 100.0f;
		StaticMesh.Object->SetActorScale3D(FVector(sx, sy, 0.01f));
		StaticMesh.Object->SetActorLocation(FVector(Width/2.0f, Height/2.0f, 0.0f));
	}
}

#if WITH_EDITOR
void ALevelLayout::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	ResizeLevel();
	Super::PostEditChangeProperty(PropertyChangedEvent);
}
#endif

When ResizeLevel() is called (after I modify Width/Height properties) I get a massive crash. 15’ later, neither visual studio nor UE4 editor are responding. I understand I cast to a mesh actor while looking for a mesh, but is the mistake that bad?

thanks man, removed and no more crashes! “usual asset reference workflow” means nothing to me at this point (ue-uber-newbie), but I found my solution: just use the TObjectIterator to find the mesh at runtime.

Hi,

you’re using ConstructorHelpers, it is pretty much self-explaining that it is meant to be used in constructor, it does ensure() check if it’s being called in constructor, which is most-likely to crash the engine in development build in this case. Either find your mesh in constructor and store it in class-member for later use, or just use the usual asset reference workflow.

Oh, to reference an asset from C++ code you just expose pointer to an asset type(everything that is derived from UObject). In your case you should add something like following in your class:

UPROPERTY(EditDefaultOnly, Category = Mesh)
UStaticMesh* LayoutMesh;

Then create Blueprint based on this class, set this property and use the Blueprint instead of native class, can’t tell you more since i don’t know how you work with the actor, spawn it manually in editor or spawn dynamically. In the latter case you can reference it somewhere the same way, but use TSubclassOf instead of type pointer, it will let you select ALevelLayout and classes inherited from it only.

Hope it helps.

Mmm this sounds overly complicated, and I lost you at blueprint creation; why should I create extra stuff? My LevelLayout actor would be spawned at each level creation, and it’s intended to be used by the editor to regenerate the level properties. I just need the attachment to the mesh as that’s the level geometry.

Creating Blueprint and setting its properties there is recommended to avoid hard-code references. It is just for a better usability, it’s totally up to you how you reference your assets :slight_smile:

By the way, you might want to take a look at ALevelScriptActor, it is present for each level and is basically just an actor, you could implement your features there, i guess.

Thanks! Sounds useful, I’ll give ALevelScriptActor a go