Correct way of setting up hierarchy for USceneComponent and UActorComponent

Hello. I have found the documentation very unclear and incomplete on about how to set up the c++ written components correctly.

Generally, I have 3 cases:

  1. UActorComponent MyComponent1
  2. USceneComponent MyComponent2
  3. USceneComponent MyComponent3 that contains another component e.g. UArrowComponent (I know it is now possible in UE5 to do it in constructor of parent component).

Each of them I want to create in C++ and be able to add them to e.g. Blueprint Type or any Actor in editor (those are not C++ actors so I cannot put anything in constructor of those actors).

In case 1. do I have to call SetupAttachment() (but it’s not available for UActorComponent) or anything to be correctly seeing my component under Actor? For now, I see that the pointer to it on Actor sometimes gets replaced and some strange things are happening.

In case 2. should I do:

AActor* actor = UActorComponent::GetOwner();
 if (actor) {
     USceneComponent* root = actor->GetRootComponent();
     SetupAttachment(root);
}

In my Component2 constructor?

In case 3, do I still need something like in case 2? And moreover when I create the sub-component, should I do it in constructor like this (and declare MyVector as UPROPERTY):

MyVector = CreateDefaultSubobject<UArrowComponent>(TEXT("MyVector"));

?
In some post I see people using it with passing this actor as argument (for me it won’t even compile) or telling each other it’s not even possible to create component in constructor of another component and that this has to be done in Actor (which sounds ridiculous if I deal with e.g. BP Actor or want to write component that can be used on already existing UE Actors).

And should I later add also:

void UMyComponent::OnComponentCreated() {
   Super::OnComponentCreated();
   if (MyVector) {
       MyVector->AttachToComponent(this, FAttachmentTransformRules::KeepRelativeTransform);
   }
}

In general, what steps are required and which are not, for it to work correctly, have correct hierarchy under Actor (and for sub-component), don’t mess with Garbage Collector etc.?

Some people are saying RegisterAllComponents should be called, but it is to be called from Actor not the Component and my Actor is e.g. BP actor or some pre-defined Unreal Engine actor type (so I cannot mess with the constructor of the actor himself). Is it really necessary? If so, maybe UActorComponent::GetOwner()->RegisterAllComponents() inside my Component’s constructor?

As you see I am not creating those at run-time or in BeginPlay(), those are “static” components that should work just like given UArrowComponent that you add to given scene Actor in editor manually and non-dynamically.

I am generally looking for clear and complete way of initialization those components.

2 Likes