Unreal crashes when setting velocity for actor that contains 2 child actor components

I am spawning an Obstacle actor that has a Box Component and 2 Child Actor Components (2 obstacles that are in the bottom and top of the screen, the box is in the middle and serves the purpose of a score hitbox). It must start moving in a certain direction the moment it spawns. For the movement I am using a Projectile Movement Component and I am setting a velocity once the main actor is spawned. But when I set the velocity for the main actor Unreal crashes. It doesn’t do that when I set the velocity for the child actors - they move like they are supposed to, but the box of the main actor stays still. I can’t seem to figure out what the problem is.

Here is the spawning function:

void AObstacleGenerator::generate()
{
	if (Spawnable) {
		float gapPosition = (FMath::RandRange(-150, 150));
		//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Green, TEXT("spawn"));
		AVerticalTile* VertTile = nullptr;
		VertTile = (AVerticalTile*)GetWorld()->SpawnActor<AVerticalTile>(Spawnable, FVector(GetActorLocation().X, GetActorLocation().Y, gapPosition), Rotation, SpawnInfo);

		VertTile->Init(speed);

		GetWorldTimerManager().SetTimer(spawnHandle, this, &AObstacleGenerator::generate, spawnTime, false);
	}
}

Here are the Init functions for the main and child actors:

void AVerticalTile::Init(float givenSpeed)
{
	movement->Velocity = FVector(0, -givenSpeed, 0);
	movement->InitialSpeed = givenSpeed;
	movement->MaxSpeed = movement->InitialSpeed;

	((APipeObstacle*)Bottom->GetChildActor())->Init(givenSpeed);
	((APipeObstacle*)Top->GetChildActor())->Init(givenSpeed);
}
void APipeObstacle::Init(float givenSpeed)
{
	movement->Velocity = FVector(0, -givenSpeed, 0);
	movement->InitialSpeed = givenSpeed;
	movement->MaxSpeed = movement->InitialSpeed;
}

Hey @boisbois2 !

Looking at your code I think I know where the problem is:

For a component, it is not necessary to handle the movement for each component separately, that is done by setting the attachments on the scene components. So what you have to do is, delete those things I quoted, then on the constructor of AVerticalTile, add this:

AVerticalTile::AVerticalTile()
{
    UPipeObstacleComponent* Bottom = CreateDefaultSubobject<UPipeObstacleComponent>(TEXT("BottomPipe")); // this initiates the component.
    Bottom->SetupAttachment(RootComponent) // this "links" the component to the main root component of your actor.
    UPipeObstacleComponent* Top = CreateDefaultSubobject<UPipeObstacleComponent>(TEXT("TopPipe")); // this initiates the component.
    Top->SetupAttachment(RootComponent) // this "links" the component to the main root component of your actor.
}

Edit: I just noticed that your APipeObstacle is an actor, if it moves at the same time that the VerticalTile, wouldn’t it be better to reparent it to a UActorComponent?

1 Like