ChildActorComponent leaving garbage everywhere

I’ve got a weapon component system that uses several UChildActorComponent in my weapon blueprint. The issue is when the weapon blueprint is changed in the editor it absolutely trashes my level.

The Actors created by the ChildActorComponents lose their association instead of being deleted before new ones are created by the ChildActorComponents… I end up with a correct copy of my weapon actor with it’s actors I can move around, but where it used to be are the unassociated Actors that appear to be spawned for the ChildActorComponents.

I am Casting ChildActorComponent’s->ChildActor to a different type of that helps any, I know there used to be an issue with this but it was fixed versions ago I thought.

After some experimentation it seems that ONLY ChildActorComponents added via C++ do this, if you add them in a blueprint instance of the class they do not have this behavior.

EDIT:

In my constructor I create them like this:

BarrelChildActorComponent = CreateDefaultSubobject<UChildActorComponent>(TEXT("BarrelChildActorComponent"));
    BarrelChildActorComponent->AttachTo(GetCollisionBox());

then in the OnConstruct I move them around like this:

BarrelChildActorComponent->SetWorldLocation(GetBarrelAttachPoint());

GetBarrelAttachPoint returns a vector of where the barrel should be attached, It just fetches the ComponentLocation of a scene component. And GetCollisionBox returns the top most root component of the parent type (ABoxComponent)

I’ve created a “fix” for this issue, which is more of a work around than anything:

// First we find the ChildActorComponents and add their current ChildActors to an array so we know they're the one we want.
TArray<AActor*> validChildActors;
	for (UChildActorComponent* childActorComponent : GetChildActorComponents()) 
	{
		ABaseWeaponPart* weaponPart = Cast<ABaseWeaponPart>(childActorComponent->ChildActor);
		if (weaponPart)
		{
			weaponPart->GetOrientationArrow()->SetVisibility(false);
			validChildActors.Emplace(childActorComponent->ChildActor);
		}
	}

   // Now we get all actors attached to the actor (The abandoned ones are still attached to the actor, just not the child actor components) and we remove anything that's not currently assigned to a ChildActorComponent.
	TArray<AActor*> attachedActors;
	GetAttachedActors(attachedActors);

	for (AActor* actor : attachedActors)
	{
		if (!validChildActors.Contains(actor))
		{
			actor->Destroy();
		}
	}

GetChildActorComponents is a custom method that returns a TArray of childActorComponents connected to the actor.

Hello MiDri,

Could you post the code that you’re using for spawning/assigning these ChildActorComponents so that we can see how you have this all set up? I’d like to try to reproduce the issue but with various different ways to do this, it would be best to try to mimic your set up.

Updated with some code, and as i’ve said in the post – this only affects UChildActorComponents added via C++. I originally prototyped this whole system in Blueprint and it works fine, I’ve also tested by adding a ChildActorComponent to a Blueprint that inherits this class and added a ChildActorComponent to it there, that one works fine but all ChildActorComponents declared in C++ have the issue.

Thank you for posting that code. For clarity’s sake, this is something that is only happening when you base a Blueprint off of this C++ class and edit it correct? When you mention that you “change” the weapon blueprint, in what way are you changing it to see this effect? From what I gather, it leaves the old child components behind and never destroys them. Is this exclusive to the editor or does it happen at runtime at all? Is there a way to clear these undestroyed actors such as closing the editor and reopening?

I’ll be trying to reproduce the issue so I can see it first hand but I want to gather as much information as possible at the same time.

It only happens when making blueprint actors based off c++ actors that have ChildActorComponents and only to those ChildActorComponents (not ones added via editor to inheriting blueprint later).

Change can be anything that triggers the OnConstruct (which changes the ChildActorComponent’s location) in the blueprint editor window, but not when the item is moved around in the world/level. However; once the issue happens it does affect the actor’s placed in the world/level and moving them around causes copies of the old actors spwaned by the ChildActorComponents to stay in the original spot (often times not even showing up in the world outlier, but still clickable and deletable.) These actors do show up when play testing the game.

After a bit of testing, it seems that any progamic movement of the ChildActorComponent can cause this. OnConstruct just best demonstrates it because it is fired so often.

Hello MiDri,

I tried setting up something close to what you have but a bit different and most likely much more simple but I’m getting different results.

Heres the code

I basically set up an actor with a mesh in it to be used for the ChildActorComponent, and then set up a scene component, a StaticMeshComponent and a ChildActorComponent on the main actor. The ChildActorComponent is then attaching itself to a socket on the top of the main actor’s mesh component. If I add in any code using AttachTo on the ChildActorComponent, it’ll begin to ignore all of my SetWorldLocation calls so I skipped that.

The results I get are that the ChildActorComponent sticks with the main actor’s static mesh but lags behind about 10 units. By lagging behind I mean if I move 10 units along the X axis in the positive direction, the ChildActorComponent’s mesh will be in the correct area, but 10 units negative of where it should be on the X axis. Is this at all similar to what you’re seeing?

I can’t use sockets (and in fact that would hide the issue, the abandoned actors will still behave like they are attached and move with the parent) I can’t use sockets due to child actor components being attached to other child actor components and not a mesh directly. I’ve writen my own “socket” like system that uses SceneComponents that are read in the OnConstruction to set location of the sub ChildActorComponents.

I was able to reproduce the problem. It seems like it may be related to attaching the child component to a component and then trying to set the location elsewhere in the OnConstruct function. I wouldn’t say that this is proper workflow but leaving behind non-referenced instances is a problem so I’ve reported the issue. For reference, the bug’s number is UE-26773. I’ll be sure to let you know of any updates made to it.

The reason I had to do this system (as opposed to sockets) is because child actor components don’t expose sockets of mesh inside them so I had to come up with my own system for connecting blueprints together.