Basically, I have a native class which handles some generic systems logic, and I want it to have a DefaultSubobject which is a blueprint-defined asset. However, I don’t want to hardcode any asset paths in c++ code, I want it to be completely editor-specified.
I’m running into a bit of a chicken-and-egg problem with the fact that CreateDefaultSubobject() has to be called in the C++ class’s constructor, which runs before the blueprint properties are assigned.
I’ve discovered the FObjectInitializer version of the class constructor, but this also requires the derived class’s class override implementation to be defined and specified in the derived class’s constructor in C++, which brings me back to the original problem.
The closest I’ve come to a working solution is to use Config properties, but the logic involved in setting that up is looking pretty hairy, given that the class’s constructor once again can’t access its own properties (although potentially, the non-CDO instances can access the CDO’s value?), and that assigning and saving that value also requires you to run the TryUpdateDefaultConfigFile() function on an instance of an object, which makes it harder to attach the config to some generic non-actor helper object.
UCLASS(Config = MyClassConfigs)
class AMyActor : public AActor
{
public:
AMyActor();
UPROPERTY(GlobalConfig, EditAnywhere) //Config
TSubclassOf<UMyBaseClassComponent> ComponentClass;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UMyBaseClassComponent* mComponent;
UFUNCTION(CallInEditor)
void SaveConfig() {
TryUpdateDefaultConfigFile();
}
};
AMyActor::AMyActor() {
if (!IsTemplate()) {
UClass* myClass = GetMutableDefault<AMyActor >()->ComponentClass.Get();
UObject* obj = CreateDefaultSubobject(FName("MyProp"), UMyBaseClassComponent::StaticClass(), myClass , true, false);
mComponent= static_cast<UMyBaseClassComponent*>(obj);
}
}
Is there a better way?