Set values using Property System (Reflection)

Hi,

It’s about the same problem of another question that I asked but I’m going to try to frame it differently:

I have strings with values that can be floats, int32s, object references, FStrings or FNames. I know how to cast the FProperty so I get the correct type, but then I don’t know how to set it to the object that has that FProperties.

I’ve seen some examples in the engine, but ultimately they use a uint8* that I assume it is the actual address of the property of the object in memory. Am I right? How can I get that? Is SetPropertyValue and SetPropertyValue_InContainer the way to go?

How can I get an UObject, get all the FProperties, cast those FProperties to FStrProperty, FObjectProperty, FFloatProperty and so on, and then set the value to the instance of that UObject?

Thanks!

Well, I found out a way, I think that’s the best way, but if someone finds a better way, please let me know.

//FObjectProperty
if (const FObjectProperty* ObjectProperty = CastField<const FObjectProperty>(PropertyHelper.Property))
{
	//get reference
	if (UObject* Object = LoadObject<UObject>(nullptr, *CellValue))
	{
		if (UObject** ValuePtr = ObjectProperty->ContainerPtrToValuePtr<UObject*>(Item))
		{
			*ValuePtr = Object;
		}
	}
}
//FIntProperty
else if (const FIntProperty* IntProperty = CastField<const FIntProperty>(PropertyHelper.Property))
{
	if (int32* ValuePtr = IntProperty->ContainerPtrToValuePtr<int32>(Item))
	{
		*ValuePtr = UKismetStringLibrary::Conv_StringToInt(CellValue);
	}
}
//FFloatProperty
else if (const FFloatProperty* FloatProperty = CastField<const FFloatProperty>(PropertyHelper.Property))
{
	if (float* ValuePtr = FloatProperty->ContainerPtrToValuePtr<float>(Item))
	{
		*ValuePtr = UKismetStringLibrary::Conv_StringToFloat(CellValue);
	}
}
//FStrProperty
else if (const FStrProperty* StrProperty = CastField<const FStrProperty>(PropertyHelper.Property))
{
	if (FString* ValuePtr = StrProperty->ContainerPtrToValuePtr<FString>(Item))
	{
		*ValuePtr = CellValue;
	}
}
//NO MATCHING PROPERTY
else
{
	UE_LOG(LogInventoryItemFactory, Log, TEXT("No Matching Property with the compatible values: '%s'"), *KeyName);
}
2 Likes

This is exactly what i want to do. But following your step, the property changing can only be seen in the details table. which means that I can not see the changing in the view port. I think may be the way to get the object and property is wrong? I did not get the instance in the level?

could you please provide me with a relative full code which also shows how to get the “item” and “property”? Much thanks