Download

Problem with cloning components from custom component

I’m trying to create a custom component based on this tutorial video in order to facilitate level design. I basically want to be able to add it to a class and have it clone all scene components that are children of the root, offsetting them until an endpoint is hit.

To go from this:
2015-02-20 00_02_47-BustableWall_.png

to this:
2015-02-20 00_05_17-BustableWall_.png

and duplicate any meshes, shapes, etc.

It seems to work well enough in the Blueprint Component window, but when I place it in the scene and play in editor, all the added components disappear.

Stopped:2015-02-20 00_08_37-DungeonBusters - Unreal Editor.png Playing:2015-02-20 00_09_17-DungeonBusters - Unreal Editor.png

This seems to clear up when I save the blueprint, or sometimes for seemingly no reason, and comes back when I change any properties of the wall.

More importantly, any added collision boxes disappear on play:

Stopped:2015-02-20 00_13_49-DungeonBusters - Unreal Editor.png Playing:2015-02-20 00_14_27-DungeonBusters - Unreal Editor.png

which I can’t find any way to fix.

Here’s the code for the component:


void UProceduralWallComponent::OnComponentCreated()
{
	Super::OnComponentCreated();

	AActor* owner = GetOwner();
	USceneComponent* root = NULL;

	if (owner)
		root = owner->GetRootComponent();

	if (!root)
		return;

	if (root->GetNumChildrenComponents() < 1)
		return;

	USceneComponent* child = root->GetChildComponent(0);

	float wallLength = Endpoint.Size();
	float width = child->Bounds.BoxExtent.Y*2/child->GetComponentScale().Y;
	FVector currentPoint = child->RelativeLocation;
	currentPoint.Y += width;

	TArray<USceneComponent*> clones;

	//clone first child of the root
	for (int i = 0; currentPoint.Y < wallLength; currentPoint.Y += width, ++i)
	{
		USceneComponent* currentComp = CloneComponent(child->GetClass(), child->GetName() + FString::FromInt(i), child);
		if (!currentComp)
			return;

		currentComp->SetRelativeLocation(currentPoint);
		currentComp->AttachTo(root);
		clones.Add(currentComp);
		owner->AddOwnedComponent(currentComp);
		currentComp->RegisterComponent();
	}

	//clone all children of the first child recursively
	CloneRecursive(child, clones);
}

void UProceduralWallComponent::CloneRecursive(USceneComponent* parent, TArray<USceneComponent*> &parentClones)
{
	TArray<USceneComponent*> children;
	parent->GetChildrenComponents(false, children);
	if (children.Num() == 0)
		return;

	for (USceneComponent* child : children)
	{
		int i = 0;
		TArray<USceneComponent*> childClones;
		for (USceneComponent* parentClone : parentClones)
		{
			USceneComponent* clone = CloneComponent(child->GetClass(), child->GetName() + FString::FromInt(i), child);
			clone->AttachTo(parentClone);
			childClones.Add(clone);
			parent->GetOwner()->AddOwnedComponent(clone);
			clone->RegisterComponent();
			if (GEngine)
				GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Yellow, clone->GetName());
			++i;
		}
		CloneRecursive(child, childClones);
	}
}

USceneComponent* UProceduralWallComponent::CloneComponent(TSubclassOf<USceneComponent> CompClass, FString CompName, UObject* Template)
{
	FName name(*CompName);

	USceneComponent* newComp = ConstructObject<USceneComponent>(CompClass, this, name, RF_NoFlags, Template);

	if (!newComp)
		return NULL;

	newComp->bCreatedByConstructionScript = true;
	newComp->OnComponentCreated();
	newComp->RegisterComponent();
	if (newComp->bWantsInitializeComponent)
		newComp->InitializeComponent();

	return newComp;
}


Any idea what I’m doing wrong?