Changing Component Owner/Outer at Runtime

During gameplay, I spawn a new component using the code below.



UStaticMeshComponent* pComponent = NewObject<UStaticMeshComponent>(pActor);

if (pComponent)
{
   pComponent->RegisterComponent();
}


The problem is, it can ONLY be attached to its owner (or any <USceneComponent> owned by the same Actor). Not to any other Actor.

How about a “reusable” component?

Presumably, the procedure is;

  • Detach the component from its current owner (pActor),
  • Change its owner to an another Actor (pActorAnother),
  • Attach the component to pActorAnother.

However, there seems to be no SetOuter(), SetOwner(), ChangeOuter(), etc. functions in the API. So, what is the proper way of changing a component’s Owner/Outer?

OK, I found it… By using the second parameter of UObject::Rename() a new Outer can be set for an object, if necessary.

Components aren’t typically meant to be used this way - they are meant to stick with the same outer for their lifetime. If you really have to however, Rename() is the method to use to change the outer.

Whether that will work in multiplayer etc, or if it creates other issues, is another question altogether.

Hi @Jambax, thanks for your kind reply.

I am planning to create a Component pool (similar to an Actor pool), and would love to gather more information on this topic.

Would you please share the source of that information? If there is such a restriction specific to Components, I presume it is mentioned somewhere on the official UE documentation.

I’m basing it on experience - It’s not specifically mentioned anywhere AFAIK, but it’s not done anywhere in the engine natively nor in any of the sample projects. Particle System Components have a pooling system but the setup is very specific to them, and they rarely if ever interact with networking at all.

You will at least have to unregister the old component properly (UnregisterComponent()) rather than just renaming it. I’d suggest checking that code out (WorldPSCPool.cpp)

By all means try it, I just wouldn’t expect it to work flawlessly in a network scenario.

Dear @TheJamsh, thank you very much for sharing your experiences.

I just checked WorldPSCPool.cpp code. Very much to the point. Perfect!

Yes, I always use RegisterComponent() and UnregisterComponent() for the sake of safety.

And, speaking of potential network issues, I totally agree with you. Most probably, it is not going to work… However, other than network issues, I have high hopes for the rest. I just have to test it thoroughly. Very thoroughly, actually.

Thanks again!

What’s the use case? Seems like if a component can be passed between actors just make it an actor? If its a component then it cannot be owned by nothing which seems like the default state of something that can switch between actors?

Hi @Shmoopy1701,

If I’m following you correctly, you mean

Before gameplay (during Actor construction):
[INDENT=2]- Create Component1 and Attach it to Actor1

  • Create Component2 and Attach it to Actor2[/INDENT]

During gameplay:
[INDENT=2]- Attach Actor2 to Actor1[/INDENT]

right? If so, yes it works… However, this method requires one parent Actor for each Component, and increases the total number of active Actors in the scene. On the other hand, getting prespawned “reusable” Components from a pool certainly reduces the number Actors used. They can be attached/detached like a LEGO brick.

Before gameplay:
[INDENT=2]- Create Component1

  • Create Component2[/INDENT]

During gameplay:
[INDENT=2]- Attach Component1 to Actor

  • Attach Component2 to Actor
    [/INDENT]

Sorry, I cannot follow you with this one. Would you please rephrase?