Correct way to get the value of a Property?

Since the TProperty iterator uses a class as input, the Property still has to be pointed to an address to get its value from. Confusing design?

Question: How to get the value address properly, or how to directly iterate properties on an object instead of its class?

for (TFieldIterator<FObjectProperty> PropertyIterator(GetClass()); PropertyIterator; ++PropertyIterator) {
	FObjectProperty* Property = *PropertyIterator;
        UObject* PropertyValue  = Property->GetPropertyValue(this);
}
1 Like

I suppose it could be confusing but it’s one of those cases where the API is built around the most utility and not necessarily around the easiest use. In your case you’ll want to look into the function ContainerPtrToValuePtr. That’ll give you the address.

void *ValueAddress = Property->ContainerPtrToValuePtr< void >( this );
UObject* PropertyValue = Property->GetObjectPropertyValue( ValueAddress );

I don’t see a version that does all that in one go, probably because the first call is part of the lower level property system and Get is part of FObjectProperty.

4 Likes

Thanks, it works

1 Like

I am using this code to get the float value of a float property:

float NewVelocity = FFloatProperty::GetPropertyValue(SomeProperty->ContainerPtrToValuePtr<void>(this));

SomeProperty has type FProperty. this is the UObject that has the property “SomeProperty”. Note that GetPropertyValue is a static function. Replace FFloatProperty according to your property type.

3 Likes

You can even use TPropertyTypeFundamentals for template functions!

void* ValuePtr = Pty->ContainerPtrToValuePtr<void>(TargetObject);
T Result = TPropertyTypeFundamentals<T>::GetPropertyValue(ValuePtr);

I’ve tested it with int32, float, bool and even FString without any problem.