How do I keep a new scene component from usurping RootComponent?

I’m having an incredible amount of frustration accomplishing what feels like a simple task- I want to give my door actor a USceneComponent, then create a blueprint of said actor and position the scene component to indicate where somebody spawning at said door should appear. All I’m doing is declaring and defining the variable:

// ADoor.h:

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
	USceneComponent* spawnTarget;

//ADoor.cpp's constructor:

	PrimaryActorTick.bCanEverTick = true;
	spawnTarget = CreateDefaultSubobject<USceneComponent>(TEXT("Spawner Target"));

For some reason whenever I do this, the entire component hierarchy of ADoor gets shuffled around, and my new scene component becomes the root component:


This completely destroys the point of using a scene component in the first place, and it results in any blueprints already placed in the scene moving unexpectedly, as the scene component suddenly becomes where they base their position on. Is there something extra I need to be doing, to keep spawnTarget a child component that I can reposition freely in the editor?

RootComponent needs to be a USceneComponent. If you don’t declare a rootcomponent (as in your constructor you go FooComponent = RootComponent;) then the first available USceneComponent will be declared root automatically. What happens here, is that you don’t have it declared, so when you create that SpawnTarget, it gets assigned as the rootcomponent.

So just define something else and declare it as the root in your constructor.

Ooh, I didn’t know that… so is the standard convention to always use a dummy root component if you need a mobile USceneComponent, like this?

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Root")
USceneComponent* genericRootComponent;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Door")
USceneComponent* spawnTarget;

genericRootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
RootComponent = genericRootComponent;
spawnTarget = CreateDefaultSubobject<USceneComponent>(TEXT("Spawner Target"));

That’s what I’ve done at least.

Also, you might want to attach your spawnTarget to the rootcomponent to make sure it shares transform if you need to move the whole assembly in runtime. Depends on what you are after.


That’s super-helpful, thank you very much for the explanation and clarifications! :slight_smile: