Download

Proper use of USceneComponents and RegisterComponent?

Problem
I’ve created a custom class inheriting from USceneComponent. When I use it, I need to call RegisterComponent on it after I create it with CreateDefaultSubobject. If I don’t, it doesn’t work properly when viewing it in the Blueprint Editor Viewport. The viewport just shows a blank gray screen, no grid, no components, nothing. But it does work when I call RegisterComponent on it after creation.


Comp = ObjectInitializer.CreateDefaultSubobject<MySceneComponent>(this, TEXT("TheName"));
Comp->RegisterComponent();
Comp->AttachTo(RootComponent);

I noticed that I don’t need to do this on any of the other default USceneComponents. For example, UCameraComponent or USpringArmComponent.

Question
Should I be overriding OnRegister or some other method in order to have it Register automatically?

TL:DR:
What is the proper way to implement a USceneComponent and RegisterComponent?

As far as I know, you don’t need to call RegisterComponent manually.

At least, I never had to.

Did you override any USceneComponent functions in your custom component?

I have to do as well and I’m not overriding any USceneComponent functions, except the constructor and TickComponent, which are both calling their corresponding Super function.

Well I have good news and bad news.

The good news is that I’ve fixed the problem. The bad news is, I’ve changed nothing… These are the worst solutions, because they solve nothing!

Taking inspiration from @Zoubi I commented out the functions I was overriding, but like @Taces was still implementing and calling the Super functions. I also removed the RegisterComponent call. I tested the asset in Unreal and it worked fine no issues. So I uncommented the code and loaded the editor back up. It still worked and looked fine. I then removed the RegisterComponent call, that I had to add in the first place to get it to work and now it works without it! :mad:

I have no idea why it works now but a day ago it was causing the viewport in my blueprint to jack up completely. I’ve tried a number of ways to get it to break again and nothing seems to break it anymore.

So bad news this time.

It’s happening again and I don’t know why. I changed nothing in the code but it renders my blueprint viewport blank. When I manually register the component and open the blueprint again it works (semi) normal. It seems the camera starts a billion units away from the center of the blueprint worldspace so I have to select the character and hit “F” to focus and bring the camera in.

Do you create blueprints out of the actor? If so, you might try to create a new BP from the C++ class.

I had sometimes discrepencies because the editor was not somehow able to have the correct internal state of the c++ class.

I know it seems a little weird, explained like that, but I guess it’s worth a try :slight_smile:

So I fixed it again, and I don’t know if this is how, but here is what I did.

I created a temp USceneComponent and it looked like this:


// Sets default values for this component's properties
UDeleteMeComponentTest::UDeleteMeComponentTest()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	bWantsInitializeComponent = true;
	PrimaryComponentTick.bCanEverTick = true;

	// ...
}

I then went and looked at mine:


UArcManager::UArcManager(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	mesh = ObjectInitializer.CreateDefaultSubobject<UProceduralMeshComponent>(this, TEXT("Generated Mesh"));
	mesh->RegisterComponent();
	mesh->AttachTo(this);

}

The difference is in the constructor.


UDeleteMeComponentTest::UDeleteMeComponentTest()
// vs
UArcManager::UArcManager(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)

I noticed mine was using FObjectInitializer and calling a Super. But the one created by default from the Editor does not.

So I removed the calls, then removed the manual RegisterComponent calls and everything seems to be working again. I don’t know if this was really the source of the problem. As when I attempt to replicate it by adding all that code back it continues to still work.

This issue seems to be a total mystery to me right now. But I will continue to document my finding here in case it helps someone or anyone who knows the issue I might be having from looking at this code.

@Zoubi
I have an Actor (KSCharacter C++) that is creating the component (ArcManager C++) as a child in its constructor. I then make a blueprint out of the Actor KSCharacter. This works with so many other classes, I only seem to have the issues when using the KSCharacter that has the custom USceneComponent and requires manual RegisterComponent (Not anymore as per the above strangely enough).

Hi Oliver,

I am trying to reproduce the issue that you described so we can look into what is happening. However, I have not been able to see the results that you have described. Would you be able to provide some additional information that will help us track this down?

  • What version of the Engine are you using?
  • Does your custom SceneComponent contain another Component?
  • Is the Blueprint that is having this issue made from a custom Actor class that contains your custom SceneComponent?
  • Does the parent class of the Blueprint contain any other components?
  • Is ProceduralMeshComponent another custom component you have created?
  • Does this only happen in your project, or are you able to reproduce it in a new project as well?
  • Would it be possible to get a screenshot of what the Blueprint editor looks like?

What I have done so far (using 4.7.6 built from source code) is to create a custom Actor class that contains a custom Scene Component that contains a StaticMeshComponent. When I made a Blueprint of the custom Actor class, the Blueprint editor was displayed as I expected.

Tim