Is it possible to have variable types in asset properties?

I’m trying to do something a little more advanced with a data asset and I’m not sure if it’s possible. I would like to have a property of a struct, but the specific struct is either determined by another property or is manually selected in the editor somehow.

For example, given the following code (roughly, I realize it’s not perfect), I would like a data asset to be able to use any of the three.


struct FTestStruct
{
}

struct FTestStructChildA : public FTestStruct
{
}

struct FTestStructChildB : public FTestStruct
{
}

Is something like this possible or does Unreal not support polymorphism in the properties?

I have a “FVariantProperty” type that can be set to be either a common blueprint type (such as int, name, string, float, vector, etc) or an array of those types, a basic variant type.

But I never turned it into sharable code, it’s buried somewhere in a project on my PC at home.

There’s also in Unreal a “Property Type Picker” struct which holds a text based info about picked type of a property on Details Panel, but that is Editor-only.

You can probably look into type Picker source and make something similar for runtime type change.

I use a UObject and have it so that when I select the object, it’ll allow me to edit that object’s properties in the data asset editor, without having to create a separate class/bp; if that’s something desirable to you.

Can you be more specific? I’m just tried adding a UObject as a property and selecting an object doesn’t give me any option to edit the data. Of course, I can just open the other asset and edit it there, but that’s not what I’ve understood you were suggesting.

This isn’t quite what I was looking for anyway. What I want is something that’s owned/scoped to the original data asset. There should be a 1:1 mapping and, ideally, no extra .asset files on disc. Basically, the equivalent of adding a component to an actor, in terms of scope.

Then my implementation should be exactly what you want. It will create an object in memory that belongs to the data asset. I’m just now starting to work on loading data assets into memory at runtime outside of editor. Since the changes are saved between editor sessions, and I can also affect the data asset data + sub uobject at runtime, I don’t foresee any issues.

PurposeAsset.h
[SPOILER]



UCLASS(Abstract) //Abstract is just a design choice
class PURPOSE_API UPurposeAsset : public UPrimaryDataAsset
{
GENERATED_BODY()

public:

UPROPERTY(Instanced, EditAnywhere, meta = (TitleProperty = Condition))
//These conditions utilize provided context data to determine if the purpose is viable to the context
//Because they are instanced, they can be created via inline editing in editor (using EditInlineNew in UCLASS())
TArray<UCondition*> conditions;



[/SPOILER]

Condition.h
[SPOILER]




UCLASS(Blueprintable, EditInlineNew) //EditInlineNew allows creation of UObject within property editor
//FSubjectSegments linked together with a conditional
class DATA_API UCondition : public UObject
{
GENERATED_BODY()
public:

UPROPERTY(EditAnywhere, DisplayName="Comparison-To")
//The subject whose value will be evaluated against another
FSubjectSegment compareTo;

UPROPERTY(EditAnywhere)
//How the compareTo will be evaluated against compareAgainst
EConditional conditional;

UPROPERTY(EditAnywhere)
//Determines the magnitude of the condition
//Does not extend score of purpose beyond 0-1
//Instead provides condition a custom weight in determining purpose viability ( 0-1 )
float weight = 1.0f;

UPROPERTY(EditAnywhere, DisplayName = "Comparison-Against")
//The subject whose value will be used to evaluate the other
FSubjectSegment compareAgainst;
};



[/SPOILER]

So EditInlineNew needs to be a part of any UCLASS() portion of a UObject you wish to spawn like this; and Instanced needs to be a part of the variable UPROPERTY() to hold that UObject

Perfect! EditInlineNew and Instanced is exactly what I was looking for. Thanks.