Download

Dynamic component creation

Hi all.
I want to spawn actor with specific amount of actor components.

Class declared like this:



...
public:
UPROPERTY(EditAnywhere)
TArray<UChildActorComponent*> childActors;
UPROPERTY(EditAnywhere)
int amount;
...


I have init code like this:



...
for (int i = 0; j < this->amount; i++)
{
tmp = this->CreateDefaultSubobject<UChildActorComponent>("Name");
tmp->SetChildActorClass(AMyActorClass::StaticClass());
tmp->CreateChildActor();
this->AddOwnedComponent(tmp);
childActors.Add(tmp);
}
...


So, than I call init code from constructor the value of “amount” is default (i.e. value setted by UnrealEditor ignored or not setted yet). Then I call init code from “Begin play” it crashes. Google says that i can init components only dyring construction.

So, how should I add components in C++ than i want to make their amount configurable vie UnrealEditor?

Outside the constructor can add a component like this:



// create component
UStaticMeshComponent* component = NewObject<UStaticMeshComponent>(owner, UStaticMeshComponent::StaticClass(), componentName);

// register component
component->RegisterComponent();

// do attachment
component->AttachToComponent(targetComponent, FAttachmentTransformRules::SnapToTargetIncludingScale, socketName);


Many thanks, seems that it works in general.

But this components not be visible in editor until I lounch the game. (I place this code inside BeginPlay function of parrent Actor)

Its strange that I can easyly pass this args in construction script in blueprint (and see results live in UnrealEditor without pressing “play”)
I expact that C++ code should has more abilities than BP scripts.

Hello,

Just an idea, you might want to look into overriding AActor:OnConstruction(), which I believe gets called each time a property is changed in a Blueprint subclass. If that works, don’t forget to remove your components when you change ‘amount’, otherwise you will just keep adding them.

Interesting effect. Example code:



for (int i=0; i< this->amount; i++)
{
tmp = NewObject<UChildActorComponent>(this, UChildActorComponent::StaticClass());

tmp->SetChildActorClass(AMyActor::StaticClass());
tmp->CreateChildActor();

// register component
tmp->RegisterComponent();

// do attachment
tmp->AttachToComponent(this->GetRootComponent(), FAttachmentTransformRules::SnapToTargetIncludingScale);
childActors.Add(tmp);
}

All objects in childActors array has the same ID and location. If I change location via editor it changed for everyone. Looks like NewObject returns me link to the same ActorComponent every time.