How to add UStaticMeshComponent to Actor outside constructor

Hi

I have a c++ actor subclass where I which to create a set of UStaticMeshComponents based on parameters provided through the blueprint.

The actor has an a variable of type UStaticMesh that is used for each of these UStaticMeshComponents that I want to create.

I decided to do this in the PostInitializeComponents function but the code is not working and breaks the editor when I try to edit a blueprint derived from my MyActor.

void MyActor::PostInitializeComponents()
{
	AActor::PostInitializeComponents();	
	if (Mesh)
	{
		float fLength = 100.f;
		m_uNumSections = 5;

		FVector vOffset(fLength, 0, 0);
		FTransform mTrans;			
		for (uint32 i = 0; i < m_uNumSections; ++i)
		{
			mTrans.AddToTranslation(vOffset);
			UStaticMeshComponent* pSection = NewObject<UStaticMeshComponent>(this);
			pSection->SetStaticMesh(Mesh);
			pSection->AttachTo(RootComponent);
			pSection->SetWorldTransform(mTrans);
			pSection->RegisterComponent();
			m_aSections.Add(pSection);
		}		
	}
}

What am I doing wrong here. I am unable to find anything in the documentation.

Thanks

Hi JamesM,

PostInitializeComponents is a function that is used to initialize components at runtime, so if the UStaticMeshComponent is being initiated in that function, it won’t be reflected in blueprints until the game is already being simulated. To appropriately assist you, can you explain for what reason you need to initialize the UStaticMeshComponent outside of the constructor? If I know your intent, it should help me pinpoint what method would be best for you.

Well the UStaticMesh (Above called Mesh) that I use to create the UStaticMeshComponents must be provided through the blueprint to the C++ class, which means I have to spawn the components after the mesh has been set. The Mesh variable is defined as a UPROPERTY.
Obviously the Mesh can’t already be set in the constructor, but by the time it reaches PostInitializeComponents it has been set.
So essentially I want to use that UStaticMesh provided, and duplicate it a few times using UStaticMeshComponents.

Also these components do not need to be modifiable through the blueprints.

I think this is probably something that should go in the construction script (or an override of OnConstruction in C++), since that will be called whenever you change a property within the blueprint editor. Make sure you reset the array though so you’re not adding more components onto the end each time.

Edit: Having said that, if you don’t need to modify the components through blueprints, maybe it would be cleaner to simply create them within BeginPlay?

Try:

void AMyShipPawn::BeginPlay()
{
	Super::BeginPlay();

    UStaticMeshComponent* NewComp = ConstructObject<UStaticMeshComponent>(UStaticMeshComponent::StaticClass(), this, TEXT("MyCompName"));
	if (NewComp)
    {
	    NewComp->RegisterComponent();
	    NewComp->SetRelativeLocation(Location);
	    NewComp->SetRelativeRotation(Rotation);
	    NewComp->AttachTo(RootComponent, NAME_None, EAttachLocation::KeepRelativeOffset);
        NewComp->SetStaticMesh(mdlMesh);
    }
}

Thanks . I will try your solution.

Thanks Detech.

Looks like BeginPlay might be the best place to do this. I will try ASAP and report back.

Okay I tried this but in the OnConstruction as suggested and it works great.

Thanks for all the help.

Thanks the OnConstruction worked great for my needs.

ConstructObject() is DEPRECATED, use NewObject(), but

UStaticMeshComponent* pSection = NewObject(this, UStaticMeshComponent::StaticClass(), NameComponent );

where FName NameComponent = FName(*(FString(“StaticMesh_”) + FString::SanitizeFloat(Counter)));

also works quicker, than ConstructObject()