TSubclassof variable used in CreateDefaultSubobject

Hi all. I’m using CreateDefaultSubobject to create a component on my character in the constructor. I want to use a TSubClassof variable to change the class type that is spawned, so that I can spawn blueprint classes. An example would be to change one AbilityComponent class in the constructor so that it spawns a different component from the TSubclassof variable, if that makes sense.
So far, I run into error after error after error, with no light at the end of the tunnel. (Errors like “Typed element was requested for before the registry was available!” and IsChildOf(ReturnType) assertion error)

Is what I’m looking for possible to do in the constructor and NOT at runtime? I can use it at runtime but I would like it as a last resort. Thanks.

This sounds like your constructor ran before another which your method depends on. CreateDefaultSubobject always felt a bit hacky to me because you can’t assume that during your class its constructor another class constructor already ran. I do use the UDeveloperSettings class all the time to set default classes in using TSoftClassPtr / TSoftObjectPtr, which I then retrieve in my constructors without errors.

Thanks! Do you think I can get an example of how this could be used? This is my current code:

if (!InventoryClass->GetClass())
	    InventoryClass = UInventoryComponent::StaticClass();
Inventory = Cast<UInventoryComponent>(CreateDefaultSubobject(TEXT("Inventory"), InventoryClass->GetClass(), InventoryClass->GetClass(), true, false));

Which gives me the error:

Assertion failed: (Ar.GetPortFlags() & PPF_Duplicate) || (GetStructureSize() >= sizeof(UObject)) [File:D:\build\++UE5\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Class.cpp] [Line: 5062]

Some extra info (in the error messages):

UnrealEditor_SurvivalGame!ConstructorHelpersInternal::FindOrLoadClass() [D:\EpicGames\UE_5.1\Engine\Source\Runtime\CoreUObject\Public\UObject\ConstructorHelpers.h:87]
UnrealEditor_SurvivalGame!ASurvivalGameMode::ASurvivalGameMode() [C:\Users\######\Documents\Unreal Projects\SurvivalGame\Source\SurvivalGame\Private\Gameplay\SurvivalGameMode.cpp:14]

Anything inheriting from UDeveloperSettings ends up as a tab in the project settings where you can configure the class property.

#pragma once

#include "CoreMinimal.h"
#include "Engine/DeveloperSettings.h"

#include "YourSettings.generated.h"


UCLASS(config=Game, defaultconfig, meta = (DisplayName = "YourSettings"))
class YOURMODULE_API UYourSettings : public UDeveloperSettings {
	GENERATED_BODY()

public:

	UPROPERTY(config, EditAnywhere, BlueprintReadOnly)
		TSoftClassPtr<UObject> YourClass;

};

.cpp where you want to access the settings:

const UYourSettings* YourSettings= GetDefault<UYourSettings>();
TSoftClassPtr<UObject> YourClass = YourSettings->YourClass;
So something like this:
UObject* X = CreateDefaultSubobject(TEXT("X"), YourClass .Get(), YourClass .Get(), true, false, false);

OR

If you are going to do this for many characters or something consider using a datatable instead of the project settings, that should work too. I’ve heard people complain datatables are not accessible in a constructor or BP constructor but that there would be a plugin for that.

1 Like

UObject’s C++ constructor isn’t really made to be that dynamic. It should be static and deterministic by design.

If you need a subobject which’s type is dynamic then you should be adding them at runtime, during BeginPlay.

2 Likes