Can't set properties of SubObject

Hi,
I am trying to create a StaticMesh subobject. But for some reason i can’t seem to figure out why i can’t set the properties of this subobject.

I hope someone knows what i am doing wrong here.

Thanks a million!!

the pointer for the CityMeshComponent is declared in the header file:

in the .H:

	UPROPERTY(EditAnywhere, Category = "StaticMeshObject")
	class UStaticMeshComponent* CityMeshComponent;

in the CPP:

ADisplayIndividual::ADisplayIndividual()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = false;
	if (!RootComponent) {
		RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("IndividualRootComponent"));
	}
	this->CityMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CityMeshComponent"));
	
	// Create a pointer to the StaticMesh
	UStaticMesh* StaticMeshAssetPtr;
	static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshObj(TEXT("StaticMesh'/Engine/EngineMeshes/Sphere.Sphere'"));
	StaticMeshAssetPtr = StaticMeshObj.Object;

	// Set the mesh
	this->CityMeshComponent->SetStaticMesh(StaticMeshAssetPtr);
	
	// Attach to root as child
	this->CityMeshComponent->AttachParent = RootComponent;

	// Set some properties.. BUT THIS DOESN'T WORK :(
	this->CityMeshComponent->SetRelativeLocation(FVector(10, 10, 10));
	this->CityMeshComponent->SetRelativeScale3D(FVector(0.5f, 0.5f, 0.5f));
}

Its not giving me any error. I can compile and place the ADisplayIndividual in the scene without any problem. The subcomponent is also there, but the values i set with:

this->CityMeshComponent->SetRelativeLocation(FVector(10, 10, 10));
this->CityMeshComponent->SetRelativeScale3D(FVector(0.5f, 0.5f, 0.5f));

are not there.
Any Ideas?

What kind of error are you getting?

Looks like the issue is that you’re calling SetRelativeLocation and SetRelativeScale3D in the constructor. These are things that happen while the game is playing and belong outside of the constructor.

For example: the game starts, you walk into a trigger, and you then set the relative location of the box 10 units forward. Same with the scale.

You need to add the Instanced property keyword (or export if you don’t want the component to be editable in editor), and since this is a default sub-object, you probably would want to set the access of the property to VisibleAnywhere instead of EditAnywhere, unless your intention is to enables blueprint user to replace the component instance in editor.

UPROPERTY(VisibleAnywhere, Instanced, Category="StaticMeshObject")
class UStaticMeshComponent* CityMeshComponent;

Now your changes should be applied to class instances.

Anyway, I am sure that the problem that you current have lies with the property not serialized propertly because it is missing the Export flag (Instanced property keyword also adds it along with RF_EditInline flag), so when unreal loads your class in PostLoad (PostLoad is called after the class constructor in which you set your transform) it zeroed CityMeshComponent because there’s no data in the disk which in turn reverting the transform that you have set in the constructor. The rule of thumb is, if an object is a default subobject or a non-transient object that is owned by the actor then the property declaration of that object should have Export or Instanced keyword.

You sir, are 100% correct! All behaves as expected after adding the export flag! Thank you!

Setting these values in the constructor does work as expected. The answer provided by Heapcleaner solved my issue. Thanks for you attempt to help anyway! <3

Dear Heapcleaner,
I hope you are willing to help me out one more time. I am basically trying to add multiple of these meshes to a single actor. I create an array, with similar property keywords as the CityMeshComponent and after creating the subobject and assigning the mesh i want to add the subobject to an array, that will eventually hold all the subobjects. The problem is that the mesh doesnt get assigned (the static mesh slot stays emtpy). Any idea how i could manage what i intend?

in .h:

// Array to hold the mesh components:
UPROPERTY(VisibleAnywhere, export, Category = "StaticMeshComponents")
	TArray <UStaticMeshComponent*> CityMeshComponentArray;

	// Mesh component of each city.
	UPROPERTY(VisibleAnywhere, export, Category = "StaticMeshObject")
	class UStaticMeshComponent* CityMeshComponent;

in .cpp:

this->CityMeshComponentArray.Empty();
	this->CityMeshComponentArray.Reserve(2);

	for (int i = 0; i < 2; i++)
	{
		// Create a unique name for each component
		FString ComponentName = "CityMeshComponent";
		ComponentName.AppendInt(i);
		
		// Create the MeshComponent
		this->CityMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(FName(*ComponentName));

		// Attach to root as child
		this->CityMeshComponent->AttachParent = RootComponent;

		// Create a pointer to the StaticMesh
		UStaticMesh* StaticMeshAssetPtr;
		static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshObj(TEXT("StaticMesh'/Engine/EngineMeshes/Sphere.Sphere'"));
		StaticMeshAssetPtr = StaticMeshObj.Object;

		// Set the mesh
		this->CityMeshComponent->SetStaticMesh(StaticMeshAssetPtr);

		// Set some properties..
		this->CityMeshComponent->SetRelativeLocation(FVector::ZeroVector);
		this->CityMeshComponent->SetRelativeScale3D(FVector(0.5f, 0.5f, 0.5f));

		// Add items to a TArray to
		this->CityMeshComponentArray.Emplace(this->CityMeshComponent);
	}

There’s nothing wrong with your code except for the part where you reserve the array and adds nothing in it.

Based on what you are trying to do, you don’t need CityMeshComponent, you only need the array, and in the for loop you attach each new default sub object to a parent and add it to the array. And now you have an array of city mesh components that are serialized property (‘marking’ an array of objects with export or instanced keyword will make each object in the array also marked as export)