Download

OnConstruction Components Not Being Destroyed?

I have the following code in my OnConstruction


void ARegion::OnConstruction(const FTransform& transform)
{
	Super::OnConstruction(transform);

	UE_LOG(LogTemp, Log, TEXT("Construction"));

	if (!RoomMesh)
		return;

	USceneComponent* sceneComponent = NewObject<USceneComponent>(this);
	sceneComponent->AttachTo(RootComponent);
	sceneComponent->RegisterComponent();
	
	UStaticMeshComponent* meshComponent = NewObject<UStaticMeshComponent>(this);
	meshComponent->AttachTo(RootComponent);
	meshComponent->RegisterComponent();
	meshComponent->SetStaticMesh(RoomMesh);

	auto bounds = RoomMesh->GetBounds();

	meshComponent = NewObject<UStaticMeshComponent>(this);
	meshComponent->AttachTo(RootComponent);
	meshComponent->RegisterComponent();
	meshComponent->SetStaticMesh(RoomMesh);
	meshComponent->SetRelativeLocation(bounds.BoxExtent * 2 * FVector(1.0, 0, 0) );
}

I’m creating a SceneComponent followed by 2 StaticMeshComponents. I have a RoomMesh that is editable so the user can define what mesh to use. As soon as the user does that I would like it to rebuild the entire “region” by using the new mesh components. I was under the impression that the entire actor is reconstructed, however, my existing components stay while it appends additional components. Is this the desired behavior? If so, what is the proper way to remove/cleanup the components before rebuilding them?

Thanks,
-jv

Hey, the way i do it is by using DestroyComponent() at the start of OnConstruction on every Component that i create in it, it works fine for me. You could try this as well : EComponentCreationMethod::SimpleConstructionScript.

You have to unregister them. That or destroy the actor, which does the same. From what I can tell, the code keeps the components registered even if you recall the construction, unless the actor gets destroyed, which will call the various component’s unregister functions, or you do it manually.

Each component has a unregister function:



UActorComponent::UnregisterComponent(). 

and this subsequently calls:



UActorComponent::OnUnRegister()
UActorComponent::DestroyRenderState()
UActorComponent::DestroyPhysicsState()


Which should do what you want.

Edit:

As Raikoh said, Calling destroy works as well, as it just calls the UnregisterComponent function on its own. Note: DestroyComponent only works on the actor it is called from, so you cant call it from another class, unless you use delegates.

UserConstructionScript would be slightly more correct as Simple indicates it is part of the hierarchy defined by the blueprint component window.

But otherwise, setting CreationMethod should do what you need.