In our project we have a blueprint data asset, filled by designers, that defines some key, when modified it automatically generates a UUserDefinedStruct object that correspond to a struct having key names as member variables. This blueprint struct is then used to create chooser tables.
Chooser Table uses FStructView for that, which relies on a UScriptStruct* and a memory address. I guess the UUserDefinedStruct should be passed as the script struct, but what about the memory address ?
I guess there is some kind of compilation for the UUserDefinedStruct that will provide a memoryblock similar to a classic FStruct and on which I can set values but I haven’t found how to do that, can you help me ?
I found the solution, which is using a FStructOnScope
Here is the code I ended up using (simplified), if that can help other people
EvaluateChooserTable(UUserDefinedStruct* ChooserTablesStruct, UChooserTable* ChooserTable)
{
FStructOnScope ChooserStructOnScope(ChooserTablesStructPtr); // will allow memory for a C++ style struct instance of the UUserDefinedStruct
// loop on UUserDefinedStruct properties to fill our struct instance
for (FProperty* Property : TFieldRange<FProperty>(ChooserTablesStruct))
{
// check property type and set value, in my case it was a game play tag, so the property is a struct property with a FGameplayTagContainer struct
if (!ChooserStructProperty->IsA(FStructProperty::StaticClass()))
{
//unexpected
continue;
}
FStructProperty* ChooserStructTypedProperty = CastFieldChecked<FStructProperty>(ChooserStructProperty);
if (ChooserStructTypedProperty->Struct != FGameplayTagContainer::StaticStruct())
{
//unexpected
continue;
}
FGameplayTagContainer* CurrentSlotGameplayTagContainer = ChooserStructTypedProperty->ContainerPtrToValuePtr<FGameplayTagContainer>(ChooserStructOnScope.GetStructMemory());
CurrentSlotGameplayTagContainer->AddTag(MyTag);
}
// now evaluate the chooser table
FChooserEvaluationContext EvaluationContext = UChooserFunctionLibrary::MakeChooserEvaluationContext();
FStructView ChooserStructView(ChooserTablesStruct, ChooserStructOnScope.GetStructMemory());
EvaluationContext.AddStructViewParam(ChooserStructView);
const FInstancedStruct EvaluateChooserStruct = UChooserFunctionLibrary::MakeEvaluateChooser(ChooserTable.Get());
UObject* ResultObject = UChooserFunctionLibrary::EvaluateObjectChooserBase(EvaluationContext, EvaluateChooserStruct, UObject::StaticClass());
}
Thanks for letting us know you resolved it! And for sharing the snippet, I’m sure it will help others too.