Adding a ThrusterComponent to an Actor at runtime

I have an actor that contains a mesh with bones, and I would like to dynamicly add UPhysicsThrusterComponent to selected bones. But I am not able to spawn an working thuster. This is what I have so far:

// Called when the game starts or when spawned
void ABaseBox::BeginPlay()
{
	Super::BeginPlay();

	auto thruster = RootComponent->CreateDefaultSubobject<UPhysicsThrusterComponent>(TEXT("Thruster")); // breakpoint
	auto thruster = NewObject<UPhysicsThrusterComponent>(this, TEXT("Thruster")); // spawn, but doesn't work
	auto thruster = NewObject<UPhysicsThrusterComponent>(RootComponent, TEXT("Thruster")); // spawn, but doesn't work

	thruster->AttachTo(RootComponent);
	thruster->SetWorldRotation(FRotator(-90.0f, 0.0f, 0.0f));
	thruster->ThrustStrength = 10000;
	thruster->bAutoActivate = true;
	thruster->bAutoRegister = true;
}

The createDefaultSubobject simply hits a breakpoint, while the other two do spawn the thruster (it shows up in the editor at runtime) but it does not seem to be processing physics, it doesn’t do anything.

The code is working as expected when createdefaultsubject is used within the constructor, however I need it to be in the BeginPlay() method, otherwise the mesh is not loaded yet and thus I am unable to find the bones.

What am I doing wrong?

Hey elquedro :slight_smile:
CreateDefaultSubobject should only be used in the Constructor of an Object.

ABaseBox::ABaseBox()
{
    //...
}

Maybe your RootComponent is also null which crashes the Engine immediately.

You can do 2 things:

  1. Creating your UPhysicsThrusterComponent with CreateDefaultSubobject in the constructor (Not by RootComponent, by “this”) and then attaching it to you RootComponent

  2. Creating you UPhysicsThrusterComponent in the BeginPlay with NewObject (Like you did. I would recommend you to use the first attempt with “this” as a first Parameter) and then call thruster->RegisterComponent(); after attaching it

Good Luck. When it doesn’t work I would gladly help you through this :slight_smile:

Thanks McStrife!

The RegisterComponent was part of the solution (the other one was quickly found). It appears that thruster->bAutoActivate and thruster->bAutoRegister are used to run RegisterComponent and Activate at BeginPlay, however these are not used in my case, because I am already at BeginPlay…
So I added the Activate and voila, my object flew straight up in the air.

This is my final solution:

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

	auto thruster = NewObject<UPhysicsThrusterComponent>(this, TEXT("Thruster")); 

	thruster->AttachTo(RootComponent); 

	thruster->SetWorldRotation(FRotator(-90.0f, 0.0f, 0.0f));
	thruster->ThrustStrength = 100000;
	thruster->RegisterComponent(); // Thanks  McStrife :)
	thruster->Activate(); // Activate the thruster directly.
}

Hey nice :slight_smile:

Glad to be able to help you

Have fun :wink: