Download

Calling CreateDefaultSubobject crashes editor!

Hello!

I have a C++ class, which calls CreateDefaultSubobject on its static mesh component in the constructor, but it crashes the editor!

I’ve read around this issue, but nothing seems to work.

Can anyone see anything wrong?
Header File:


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Actor.h"
#include "InteractiveObject.h"
#include "RSGenerator.generated.h"

UCLASS()
class RSGAME_API ARSGenerator : public AInteractiveObject
{
	GENERATED_BODY()

	UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
	class USkeletalMeshComponent* GenMesh;

public:	
	// Sets default values for this actor's properties
	ARSGenerator();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

};


Source File:


// Fill out your copyright notice in the Description page of Project Settings.

#include "RSGame.h"
#include "RSGenerator.h"


// Sets default values
ARSGenerator::ARSGenerator()
{
	GenMesh->CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Mesh"));
}

// Called when the game starts or when spawned
void ARSGenerator::BeginPlay()
{
	Super::BeginPlay();
	
}



try this



GenMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("GenMesh"));


No difference, the editor still crashes

try commenting out the line? if its still crashing after that, the problem likely lies elsewhere

Nope, it is defintely caused by that one line

So, what does the call stack and output log say after the crash?

Here’s the dump…

Does AInteractiveObject inherit from AActor, or is it a plain UObject?

Yes, it inherits from AActor. I can paste that class if it will help…
Source:



// Fill out your copyright notice in the Description page of Project Settings.

#include "RSGame.h"
#include "InteractiveObject.h"
#include <typeinfo>


// Sets default values
AInteractiveObject::AInteractiveObject()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	meshcomp = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Skeletal Mesh"));
	meshcomp->CastShadow = true;
	RootComponent = meshcomp;

	hitbox = CreateDefaultSubobject<UBoxComponent>(TEXT("Hitbox"));
	hitbox->OnComponentBeginOverlap.AddDynamic(this, &AInteractiveObject::BeginOverlap);

	hitbox->SetRelativeLocation(FVector::ZeroVector);
}

// Called when the game starts or when spawned
void AInteractiveObject::BeginPlay()
{
	Super::BeginPlay();

	hitbox->SetRelativeLocation(FVector::ZeroVector);

	epressed = false;
	withinrange = false;
}

// Called every frame
void AInteractiveObject::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );
	if (nightguard->IsValidLowLevel())
	{
		epressed = nightguard->InteractingCPP;
	}
	if (withinrange && epressed)
	{
		OnInteract();
	}
}

void AInteractiveObject::OnInteract()
{
	
}

void AInteractiveObject::BeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	//if (typeid(OtherActor) == typeid(nightguard))
	//{
		nightguard = (ARSGameCharacter*) OtherActor;
		withinrange = true;
	//}
}
void AInteractiveObject::EndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	//if (typeid(OtherActor) == typeid(nightguard))
	//{
		withinrange = false;
	//}
}


(I know EndOverlap wouldn’t work)

Header:



// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Actor.h"
#include "RSGameCharacter.h"
#include "InteractiveObject.generated.h"

UCLASS()
class RSGAME_API AInteractiveObject : public AActor
{
	GENERATED_BODY()

	ARSGameCharacter* nightguard;

public:	
	// Sets default values for this actor's properties
	AInteractiveObject();

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Collision")
	UBoxComponent* hitbox;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Mesh)
	USkeletalMeshComponent* meshcomp;

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	virtual void OnInteract();

	UFUNCTION()
	void BeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResultr);
	
	UFUNCTION()
	void EndOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResultr);

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Interactivity")
	bool withinrange;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Interactivity")
	bool epressed;
	
};

Can you see anything?

Try removing the class specifier " class USkeletalMeshComponent* GenMesh;"

Compile complete! Thank you!

No problem :slight_smile:

Hang on, it turns out that the CreateDefaultSubobject was just commented out :frowning:

It’s still broken D:

I now have a mesh component in my parent class, so it isn’t really a problem, but it would be nice to know why this is happening…

Hey there, I have similar issue.

I have an MyActor class derived from AActor class. I want to attach capsule component to MyActor object in runtime, so that I write following code


    FVector NewLocation = FVector(0.f, 0.f, 0.f);
    MyActor* NewActor = GetWorld()->SpawnActor<MyActor>(ARTSActor::StaticClass(), NewLocation, FRotator::ZeroRotator);
    UCapsuleComponent* CapsuleCollider = CreateDefaultSubobject<UCapsuleComponent>(FName("Capsule"));
    CapsuleCollider->AttachToComponent(GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);

Whenever CreateDefaultSubobject function called editor crashes with following error.


Fatal error: [File:D:/Build/++UE4/Sync/Engine/Source/Runtime/CoreUObject/Private/UObject/Obj.cpp] [Line: 107] No object initializer found during construction.

If I move CreateDefaultSubobject and AttachToComponent functions to constructor of MyActor class, It works fine. Is there anyone know, why is this happening?

LOL, for me, this was using an unitialized pointer like this:

OverlapComp->CreateDefaultSubobject<UBoxComponent>(TEXT("OverlapComp"));

When I really meant to create an object like this:

OverlapComp = CreateDefaultSubobject<UBoxComponent>(TEXT("OverlapComp"));
5 Likes

Thank you so much for that. That fixed it for me as well.

No idea why I did that, but I’m glad I’m not alone.

5 Likes

CreateDefaultSubobject can’t be used outside of the class constructor. As the name suggests, it’s for creating a default sub-object.

To create actor components at runtime you must use NewObject, then manually register it. Do NOT give the component a name, use the default NAME_None parameter.



UMyComponent* NewComp = NewObject<UMyComponent>(Actor, ComponentClass);
check(NewComp);

NewComp->RegisterComponent();


2 Likes

Been there, done that! :rofl: :rofl: :rofl: