Conditionally Create Components in Constructor

rayunforsaken
Wed, 29 May 2019 07:19:22 +0000
C++

I want my BaseItem classes to support either a static mesh or skeletal mesh, and I don’t want to create 2 separate components if only one is going to be used. I’ve set up some properties in an attempt to support that:

	UPROPERTY(EditAnywhere, Category = "Mesh")
	bool bUseSkeletalMesh;

	UPROPERTY(EditAnywhere, Category = "Mesh", meta=(EditCondition="bUseSkeletalMesh"))
	USkeletalMeshComponent* m_skeletalMeshComp;

	UPROPERTY(EditAnywhere, Category = "Mesh", meta=(EditCondition="!bUseSkeletalMesh"))
	UStaticMeshComponent* m_staticMeshComp;

And in the constructor:

if (!bUseSkeletalMesh)
{
	m_staticMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
	RootComponent = m_staticMeshComp;
}
else
{
	m_skeletalMeshComp = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("SkelMesh"));
	RootComponent = m_skeletalMeshComp;
}

First of all, in order for this to work after recompiling, I had to cache off any changed values (such as bUseSkeletalMesh) to a static editor object, since those get wiped during the recompile, then retrieve and set them in the constructor. I also set up the new component objects in PostEditChangeProperty, in response to the bUseSkeletalMesh property being changed:

	FName memberName = PropertyChangedEvent.GetPropertyName();
	if (memberName == GET_MEMBER_NAME_CHECKED(AUSCreatable, bUseSkeletalMesh))
	{
		if (bUseSkeletalMesh)
		{
			StaticMeshComp = nullptr;
			SkeletalMeshComp = NewObject<USkeletalMeshComponent>(this, TEXT("SkeletalMesh"));
		}
		else
		{
			SkeletalMeshComp = nullptr;
			StaticMeshComp = NewObject<UStaticMeshComponent>(this, TEXT("StaticMesh"));
		}

		SetRootComponent(GetMeshComp());
		m_boxComp->AttachToComponent(RootComponent, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
	}

What I’m seeing is that while I’m in the editor, I check UseSkeletalMesh, the component gets properly created by the above code. I then set the static mesh in the component to a mesh, compile it, save it, and all is well.

THE PROBLEM: when I reload the editor, both the static and skeletal mesh components are null, as if no data for either was serialized/deserialized. I’m assuming I’m missing some registration call or something to make sure these NewObject-created components get serialized properly, but I’m not sure…

4 posts - 1 participant