[Data] Flexible Data
We want to create a widget depending on the object data type we have. The default widget will be a W_Object UUserWidget, but we also want to create specific widgets like W_Planet
Our subsystem will create the widgets depending on the data type (used as a type tag to have multiple overloads)
The subsytem
UCLASS()
class UARKSubSystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
UUserWidget* GetWidget(UObject* Object, const UARKObjectData*)
{
// Create an object widget
auto* Widget = CreateWidget<UARKObjectWidget>(GetWorld(), ObjectWidget);
Widget->Object = Object; // Give our object to the widget
return Widget;
}
UUserWidget* GetWidget(UObject* Object, const UARKPlanetData*)
{
// Create a planet widget
auto* Widget = CreateWidget<UARKObjectWidget>(GetWorld(), PlanetWidget);
Widget->Object = Object; // Give our object to the widget
return Widget;
}
};
Default widget for base data
GetWidget could be call from a base class or an interface passing the object containing the data (Data->GetWidget(this);
)
UCLASS(BlueprintType, Blueprintable, EditInlineNew, DefaultToInstanced, CollapseCategories)
class UARKObjectData : public UObject
{
GENERATED_BODY()
public:
virtual UUserWidget* GetWidget(UObject* Object)
{
// Calling GetWidget with this will call the UARKObjectData overload
return GetWorld()->GetGameInstance()->GetSubsystem<UARKSubSystem>()->GetWidget(Object, this);
}
};
Specific widget for planet data
UCLASS(BlueprintType, Blueprintable)
class UARKPlanetData : public UARKObjectData
{
GENERATED_BODY()
public:
virtual UUserWidget* GetWidget(UObject* Object) override
{
// Calling GetWidget with this will call the UARKPlanetData overload
return GetWorld()->GetGameInstance()->GetSubsystem<UARKSubSystem>()->GetWidget(Object, this);
}
};
The base for our widgets
UCLASS()
class UARKObjectWidget : public UUserWidget
{
GENERATED_BODY()
public:
// Get the object from the widget
UObject* GetObject() const;
// Our objects store data so we can just get the datas from a base or an interface
UNGObjectData* GetData() const
{
// Using an interface
return Cast<IARKObject>(Object)->GetData();
}
UPROPERTY()
UObject* Object;
};
We can now Get/Make a widget from a base object/interface and get the data from this widget with a hierarchy. YAY !