Correct usage of AActor::RootComponent in extended classes.

Hi,

I am using Unreal Engine 5.5.3.

Question:

If you create a AActor object in your scene and select it, it displays the hierarchy. In the hierarchy, select ‘DefaultSceneRoot’. There you can edit the ‘Transform’ menu just fine.

If you extend a class from AActor like this:

-- A.h
class A : public AActor
{
   A();
};
-- A.cpp
A::A()
{
   RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root")); 
}

If you create a Blueprint from this class A, you can not edit RootComponent anymore. Is that the intended behavior?

Hello, you’re going to want to make a UProperty variable for your component in the .h and make sure it is marked VisibleAnywhere so you can see and edit the values of the component.

Like this:

-- A.h

class USceneComponent;

class A : public AActor
{
   A();

UPROPERTY(VisibleAnywhere)
USceneComponent* RootSceneComponent;

};
-- A.cpp
#include "Components/SceneComponent.h"

A::A()
{
   RootSceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root")); 
   RootComponent = RootSceneComponent;
}

This will allow the property to be editable in your BP.

1 Like

Thanks for your fast reply.

I understand that you can make it work the way you pointed out. I am just curious on why I need a local variable with a UPROPERTY with VisibleAnywhere to be displayed and edited. I think it is strange behavior that you have an variable that is visible from AActor but not if you extend it.

Is this RootComponent special in any way?
Shouldnt it be EditAnywhere to be editable?
Is it a custom view?

Thanks again

It is the intended way to show like that since you did not change the specifiers of the property you were trying to set. You tried to make the RootComponent a default subobject, which by default, is not able to be edited by BP. The specifiers are the things that make anything in code able to do certain things in the editor. The same thing will happen if you just make a default subobject and attach it to the RootComponent, rather than setting it.

While EditAnywhere is still correct based on its description in the documentation, VisibleAnywhere gets you the same results to edit defaults for components, looking like the normal way the editor displays the info in the details panel.

The main difference comes in when you make the Actor itself a variable in another UObject. It displays the component with it being Editable even in the level editor, which is usually too much information and clutters what you actually need from that Actor as a variable.

Hi,

Thanks for the explanation. I think I understand a little more now.

Still I think my question is not exactly answered. I came up with a better example. Take a look in the following hierarchy.

-- A.h
class A : public AActor
{
public:
   UPROPERTY(VisibleAnywhere)
   USceneComponent *C;
};
-- B.h
class B : public A
{
public:
   B();
};
-- B.cpp
B::B()
{
   RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
   C = CreateDefaultSubobject<USceneComponent>(TEXT("C"));
   C->SetupAttachment(RootComponent);
}

This describes better my question. In this example, you CAN edit C but you CAN NOT edit RootComponent even though both of them are declared in a parent class. In A.h C is declared with UPROPERTY(VisibleAnywhere) so these UPROPERTY() are transfered when extended. In AActor the RootComponent is not even declared as VisibleAnywhere but you can edit it. Further more if you extend from AActor you can not edit RootComponent’s properties anymore. I want to understand that behavior.

Best,

You’ll need a variable in your actor header for both components. Probably want the “EditAnywhere” tag as well.

Also, when adding the root component, we always explicitly call:

"actor->SetRootComponent(newComponent);"

Any components you want editable in details panel will need a variable in the actor header with UPROPERTY(). You’ll want UPROPERTY on your components anyway because AFAIK they won’t save correctly, be eligible for garbage collection, hold static lighting, or other things without a UPROP.

The common actor “RootComponent” variable is the root component cast to a SceneComponent. But you still need a uproperty variable for whatever you add as the root component.