Download

Is it possible to create instance of BP type in c++ Ctor

Hi

I have been trying to use NewObject to create instance of BP type

private:
	UPROPERTY(VisibleAnywhere, Category = "NPC Data")
	TSubclassOf<class UC_NpcCtrlData> mvo_bp_NpcCtrlDataCls;


	UPROPERTY(VisibleAnywhere, Category = "NPC Data")
	UC_NpcCtrlData* mvo_bp_pNpcCtrlData;

static ConstructorHelpers::FClassFinder<UC_NpcCtrlData> lc_ch_npcCtrlDataCls(
		TEXT("Blueprint'/Game/ThirdPersonCPP/Blueprints/AI/Controller/BP_NpcCtrlData.BP_NpcCtrlData_C'")
	);

	verifyf(lc_ch_npcCtrlDataCls.Succeeded() == true, TEXT("Failed to find Control Data BP"));

	mvo_bp_NpcCtrlDataCls = lc_ch_npcCtrlDataCls.Class;
		
	mvo_bp_pNpcCtrlData = NewObject<UC_NpcCtrlData> (mvo_bp_NpcCtrlDataCls->StaticClass());
	verifyf(mvo_bp_pNpcCtrlData != nullptr, TEXT("Invalid Char COntrol Data pointer"));

But even though i get no errors seems the object is not being created, thus any attempt to access the object later results in exception.

My questions, does NewObject<>() work in cpp ctor

If not what is best way to create instance of BP type inside cpp ctor

You have two main problems here, both with your call to NewObject.

First, the first parameter to NewObject isn’t the class type but the outer (sort of the owning object). In your case you can probably use this as the first parameter.
Second, you don’t need to call anything with your TSubclassOf member when passing it to NewObject. You can pass it directly in as the second parameter to NewObject.

Thanks very much for that i changed the code to match your correction.
Also It looks like its impossible to use NewObject to create a UObject inside constructor, it has to be further on the initialisation process in places like BeginPlay.

Still would be nice to know for sure if NewObject wount work in Ctor.

It gets confusing when you think actor objects and components can be created in Ctor using CreateDefaultSubobject<>(). But not UObjects, it seems UObjects have to wait till BeginPlay.

Learn about UObject flags.
Specifically:

RF_ClassDefaultObject
RF_ArchetypeObject

if ( this->HasAnyFlags( RF_ClassDefaultObject ) )
{
    // print logs here to see what editor does
    // every time this code runs and learn why
}

Thanks very much will follow that trail.
I saw some info on this flags in google searches, but did not want to go that deep at the time.
I take the dive now
cheers

You may be right, it’s been a while since I’ve had to do anything like that. However I don’t believe there’s any limitation in the types that you use with CreateDefaultSubobject. I definitely have at least one call in my project that creates a non-component UObject and it works just fine.

Thanks again finally got it working using this , based on your suggestion

if (!this->HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
	{
		mvo_bp_pNpcCtrlData = NewObject<UC_NpcCtrlData>(this, mvo_bp_NpcCtrlDataCls, TEXT("NpcCtrlData"));
		verifyf(mvo_bp_pNpcCtrlData != nullptr, TEXT("Invalid Char COntrol Data pointer"));
	}

Note it now works inside the constructor.
Previously it would crash as the editor was loading calling all the constructors.

1 Like