How do I properly procedurally add components in C++?

I am wanting to procedurally add my generated terrain mesh components when the player first starts and as the player walks around.

Right now I’m calling a function from blueprints and in that function I have this, along with other code:

FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = Instigator;
UGeneratedMeshComponent* mesh = World->SpawnActor(MeshComponent, Location, FRotator::ZeroRotator, SpawnParams);

MeshComponent is a property that is assigned in blueprints:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Generation)
TSubclassOf MeshComponent;

Doing it this way I get an exception:

0xC0000005: Access violation reading location 0x00000000000004E8.

So I figured maybe I’m doing it wrong, how can I do it properly?

Hello,

you want to add a component runtime ?

Try this:

AActor* pActor= ....... pointer to my actor 

UMyComponent* pComponent = NewObject<UMyComponent>(pActor);
pComponent->RegisterComponent();

Your code at line 4 spawns an actor, and does not add components to it.
SpawnActor also returns an actor, and not a component. It should afaik not compile.

Greetings…

Thank you! That makes much more sense than what I was doing. You should add your reply as an answer so I can mark it correct

:slight_smile: you are welcome

Is there a way to do this if you don’t know the component type? For example, imagine you are given an array of the form

TArray& ComponentArray;

and you want to do something like create the component in ComponentArray[i]. Since you don’t know the specific component type, you can’t use NewObject. Also, I want to do this in a construction script so I can’t use spawn.

Any thoughts would be much appreciated.

Thanks,
-X

Hi, that means, you want to clone components ?

I have not done this myself, but I guess this should work:

As far as I know you can always get the type of an UCLASS by using the reflection-system-method MyObject::StaticClass().

So, if you do not know the type, you can always clone an unknown component by creating an UActorComponent and using the MyObject::StaticClass() of the source object.

Code:

UActorComponent* newComp = ConstructObject(ComponentArray[i]::StaticClass(), this);

Hope this helps :slight_smile:

See also When is valid time to create Subobjects/Components which explains an important distinction.

ConstructObject is not used anymore from v4.9

Why do you need “registerComponent”?. I did it without it, and the component appeared anyway.

For garbage collection and memory management by the engine.