Entire project broken after using RootComponent

Firstly, I am very new to UnrealEngine but have been dabbling in developing with it using C++, so if I’m going down the wrong route: just say.

My first little project I set myself was to make my own class that would be a cube that spun and bobbed up and down.

During this I wrote, in my class’ constructor the line:

[FONT=courier new]origin = RootComponent->GetRelativeTransform().GetLocation();

In the hopes to save that position, for use later in the bobbing up and down code.

However, when compiling this change, the UE4 editor crashed with no proper error codes. I have replicated this crash 3 times: as soon as I add that line the compile will result in a crash. And furthermore, the project will crash every time when opening it, before the editor screen fully opens, rendering it totally broken.

If anyone has any information as to why this line results in such behaviour or any ways to fix the project and recover it, I’d really appreciate it.

I can also provide crash logs if needed.

Thanks in advance.

The RootComponent of an actor is generally set in the Constructor.
Do you have something like this in the classes constructor before trying to access it?



    USceneComponent* TransformComponent = CreateDefaultSubobject(TEXT("TransformComponent0"));
    RootComponent = TransformComponent;


Yes,

In the header:


[FONT=courier new]UStaticMeshComponent* mesh;

In the cpp:


[FONT=courier new]mesh = CreateDefaultSubobject(TEXT("Cube"));
mesh->SetupAttachment(RootComponent);

Nah, you’re looking for something that says “RootComponent =” something something :slight_smile:

So RootComponent is not defined by the engine at all?

And that this crash could be just down to me referencing it when it’s undefined?

No, a root component is not automatically created by the engine for a C++ class.
Yes, by the sounds of it, that is the problem.

My class inherits from Actor, is that still the case?

And also, if that was the case, wouldn’t the line


 
 mesh->SetupAttachment(RootComponent); 

also be invalid?

Maybe not. If Mesh is valid but RootComponent is null then I’m guessing SetupAttachment ignores nullptrs being passed in. To emphasis Kris’s point, the root component in the chain UObject | AActor | APawn | ACharacter isn’t set until ACharacter’s constructor I’m not sure what your parent class is but you’ll want to look in the various constructors to see if it sets a root component. Or just set one in your constructor:



RootComponent = mesh;


Honestly though, a quick view in the debugger should tell exactly what’s wrong with your original line of code (though 99.9% sure it’s you don’t have a root component).

Function to add an arbitrary static mesh to an actor with option of making it ROOT and attaching it to something. Should help you get started.



/**
* Add non-interactive component to actor and a return a pointer to it.
* Must be called in constructor.
*/
UStaticMeshComponent* AddStaticComponent(FString unrealName, FName socketName, FString meshAssetPath, bool isRoot = false, UMeshComponent* attachParent = nullptr);

/**
*  Add non-interactive component to actor and a return a pointer to it.
* Must be called in constructor.
*/
UStaticMeshComponent* AInteractiveActor::AddStaticComponent(FString unrealName, FName socketName, FString meshAssetPath, bool isRootComponent, UMeshComponent* attachParent/* = nullptr*/)
{
 // create new component and attach to root or set as root
 UStaticMeshComponent* newComponent = CreateDefaultSubobject<UStaticMeshComponent>(FName(*unrealName));
 if (isRootComponent)
 {
  RootComponent = newComponent;
 }
 else
 {
  if (attachParent)
  {
   newComponent->SetupAttachment(attachParent, socketName);
  }
  else
  {
   newComponent->SetupAttachment(RootComponent, socketName);
  }  
 }

 // find static mesh asset and assign it to new component
 ConstructorHelpers::FObjectFinder<UStaticMesh> newAsset(*meshAssetPath);
 if (newAsset.Succeeded())
 {
  ((UStaticMeshComponent*)newComponent)->SetStaticMesh(newAsset.Object);
 }
 else
 {
  LOG_ERROR("%s: assigned invalid static mesh asset!", *unrealName);
 }

 // return pointer to new component
 return newComponent;
}


Calling it would look like this:



 UStaticMeshComponent* bodyMesh = AddStaticComponent("ComponentName", "AttachSocketName", "/Game/Models/MyMeshName", true);