Adding Subcomponents to a USceneComponent in Unreal 5 C++

Problem

I’ve encountered multiple situations where I needed to create a custom USceneComponent in C++ that contains other USceneComponent-based subcomponents as part of its default structure. However, Unreal Engine does not seem to natively support this pattern in a straightforward way.

Use Case

One specific scenario involved needing a USphereComponent that always has an attached UWidgetComponent. While I could manually add the UWidgetComponent in Blueprints or during runtime, this approach feels inefficient and error-prone. Ideally, I would like to define a USceneComponent subclass in C++ that automatically initializes and maintains its own child components without requiring external setup.

Potential Reasons for Limitation

From my understanding, the reason why USceneComponent subclasses cannot own other components may be tied to Unreal’s component serialization system. When an AActor is constructed, its components are serialized early in the process. If a USceneComponent were to dynamically create and register additional subcomponents after this point, they might not be properly serialized, leading to issues with saving, loading, or modifying them in the editor.

That being said, I find it hard to believe that Unreal does not have a built-in solution for this. The closest alternative appears to be UChildActorComponent, but from what I’ve read and experienced, Child Actors can introduce additional complexity and can be difficult to manage in code.

If This Isn’t Possible, What’s the Right Approach?

If Unreal’s architecture simply doesn’t allow USceneComponent subclasses to own their own subcomponents in a clean way, what is the best way to rethink this pattern?

  • Should I instead be thinking in terms of a single USceneComponent that dynamically requests its dependencies from the owning AActor?
  • Is it better practice to structure this as an AActor rather than a USceneComponent?
  • Are there Unreal-native alternatives that achieve the same modularity while avoiding issues with serialization and ownership?

Would appreciate any insights from those who have dealt with similar scenarios.

Update: Partial Solution Found

I’ve found a way to achieve the desired behavior to some extent. Here’s what I tested:

I created UTestSphereColliderComponent, a USphereComponent with a UWidgetComponent as a sub-component:

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent), Blueprintable)
class TEST_API UTestSphereColliderComponent : public USphereComponent
{
	GENERATED_BODY()

public:
	UTestSphereColliderComponent();

	virtual void OnRegister() override;

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sub-Component")
	TObjectPtr<UWidgetComponent> WidgetComponent;
};
UTestSphereColliderComponent::UTestSphereColliderComponent()
{
	WidgetComponent = CreateDefaultSubobject<UWidgetComponent>("Widget Component");
	WidgetComponent->SetupAttachment(this);
}

void UTestSphereColliderComponent::OnRegister()
{
	Super::OnRegister();
	WidgetComponent->SetupAttachment(this);
}

Observations:

  • The data persists, and the WidgetComponent functions correctly.
  • However, the WidgetComponent does not appear in the Components panel in Unreal.
  • It does appear in the Details panel when selecting the UTestSphereColliderComponent, allowing for editing.

Additionally, when UTestSphereColliderComponent is used inside an AActor, the expected behavior occurs—the WidgetComponent appears correctly in the Components panel:

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent), Blueprintable)
class TEST_API ATestActor : public AActor
{
	GENERATED_BODY()

public:
	ATestActor();

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
	UTestSphereColliderComponent* TestSphereColliderComponent;
};
ATestActor::ATestActor()
{
	TestSphereColliderComponent = CreateDefaultSubobject<UTestSphereColliderComponent>(TEXT("Test Sphere Collider"));
	RootComponent = TestSphereColliderComponent;
}

Conclusion:

While this method allows for proper functionality and editing in the Details panel, it does not fully resolve the issue of sub-components appearing in the Components panel when used as a standalone component.
If anyone knows a way to make a standalone component’s sub-components appear in the Components panel as well, I’d love to hear your insights!

From the C++ definition:

class USceneComponent : public UActorComponent

This means a USceneComponent must belong to an AActor, it cannot belong to anything else. It’s nothing to do with how data is serialized.

In general the UE pattern is that the AActor will own the components. You can then set up “attachments” so the components have the hierarchy that you expect.

In SceneComponent.h see:

/** 
 * Initializes desired Attach Parent and SocketName to be attached to when the component is registered.
 * Generally intended to be called from its Owning Actor's constructor and should be preferred over AttachToComponent when
 * a component is not registered.
 * @param  InParent				Parent to attach to.
 * @param  InSocketName			Optional socket to attach to on the parent.
 */
ENGINE_API void SetupAttachment(USceneComponent* InParent, FName InSocketName = NAME_None);

If you want a component to be responsible for spawning other components, it can do that, but it needs to set its own GetOwner() (an AActor) as the owner of the components it spawns. It can then SetupAttachment so those components are attached to it in whatever hierarchy it wants.

Example code:

//////////
// In your SceneComponent header:
//////////

UPROPERTY()
TObjectPtr<USceneComponent> ChildComp1;

UPROPERTY()
TObjectPtr<USceneComponent> ChildComp2;

//////////
// In your SceneComponent constructor:
//////////

ChildComp1 = NewObject<USceneComponent>(GetOwner());
ChildComp1->SetupAttachment(this);

ChildComp2 = NewObject<USceneComponent>(GetOwner());
ChildComp2->SetupAttachment(ChildComp1);

Resulting hierarchy:

  • GetOwner() (Actor that owns your Scene Component)
    • this (your main Scene Component)
      • ChildComp1
        • ChildComp2

Hey Xist,

I appreciate the response, but I wanted to clarify a few things since there are some misunderstandings in your answer.

GetOwner() is Not Available in a Component Constructor

You mentioned using GetOwner() in the constructor to create and attach child components, but this won’t work because at the time the component is being constructed, it does not yet have an owner during Unreal’s class setup phase. However, once Unreal fully loads and assigns an owner, GetOwner() will return a valid value—but by then, issues arise where Unreal can freeze when compiling the actor.

This can be tested by adding a simple check inside the constructor:

if (AActor* Owner = GetOwner())
{
    ChildComp1 = NewObject<USceneComponent>(Owner);
    ChildComp1->SetupAttachment(this);
}
else
{
    UE_LOG(LogTemp, Error, TEXT("Component has no Owner in constructor!"));
}

During initial loading, this will always hit the error message because the component does not yet have an owner. Later, once assigned to an actor, Unreal may encounter unexpected behavior or even freeze when recompiling the actor. This suggests that while Unreal does eventually assign an owner, it’s unreliable to assume GetOwner() will be safe in the constructor.

A correct approach would be to create and attach child components inside BeginPlay() or InitializeComponent(), where the owner is guaranteed to be set and Unreal avoids these issues. However, the downside to this approach is that the sub-components will only be editable while the game is running and not in the editor, which can limit flexibility when working within the Unreal Editor.


USceneComponent Ownership

I think there might have been some confusion about my question. Yes, I’m fully aware that a USceneComponent must belong to an AActor—that wasn’t the issue I was bringing up. What I was referring to is that a USceneComponent cannot, as part of its own construction, create and attach other USceneComponent-derived components. Specifically, you cannot use a USceneComponent’s constructor to create and attach child components (like ChildComp1 attaching to this directly). It’s only possible for an AActor to create and manage multiple USceneComponents and handle their attachment to each other, as you correctly mentioned.

This limitation is likely tied to Unreal’s serialization system, as components need to be serialized in a particular order during actor construction. If we allow USceneComponent subclasses to create their own children, Unreal would have trouble serializing them properly, especially when saving/loading or editing them in the editor. So, it’s not a matter of USceneComponent not belonging to an AActor; it’s about how Unreal handles serialization and dynamic creation of child components.


What’s the Right Way?

So, if it’s not possible to have a USceneComponent attach another USceneComponent to itself, what would be the right way to think about this problem? In my case, I want to create a component (like a USphereComponent) that always has a UWidgetComponent attached to it, with both being editable at editor time. Is there a better approach or pattern in Unreal that could allow for this kind of setup?

Looking forward to hearing your thoughts!

You’re right, apparently you can’t create sub-components in a component constructor. You can do it in BeginPlay, but that doesn’t help you be able to edit the sub-component settings in the Editor.

If you need to edit the “sub-components” in the Editor, you should probably be defining them in the owning Actor’s constructor to create all the components there so they’re included in the Actor CDO.

If your objection is to repetitive typing of the same boilerplate constructor C++, you could make a macro. GAS, for example, uses lots of macros so you can write a 1-liner rather than a 10-liner that’s always the same with only minor variable name changes.