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:
to this:
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: Playing:
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: Playing:
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?