Field Notify Properties - DoubleDeez/MDFastBinding GitHub Wiki
Field Notification is a new feature in Unreal 5.1 that provides an interface (INotifyFieldValueChanged
) for subscribing to changes to specific properties within a UCLASS.
Properties that are exposed to the INotifyFieldValueChanged
interface are marked with the FieldNotify
UPROPERTY specifier, this lets the Unreal Header Tool (UHT) know to generate code that exposes it.
To add FieldNotify
properties to your class, you'll need to inherit from a class is already setup to support Field Notification (eg. UWidget) or set up your class to support it.
If you need to setup a class to support Field Notification, there's 2 ways to go about it depending on whether your class will have FieldNotify
properties itself or if it's a base class and only child classes will have FieldNotify
properties.
If you don't have FieldNotify
properties on your class, you can mimic the implementation UMVVMViewModelBase
does. You'll need to implement INotifyFieldValueChanged
, add a UE::FieldNotification::FFieldMulticastDelegate Delegates
member to bind any listeners of your field notify properties to, and a TBitArray<> EnabledFieldNotifications
member to track which fields have listeners bound. I've created this Gist as an example of a base class that supports Field Notification (UFieldNotifyObjectBase
) and a child class that has a FieldNotify
property on it (UExampleFieldNotifyObject
)
If you do have FieldNotify
properties on your class, you can mimic the implementation UWidget
does. You'll need to implement all the methods from INotifyFieldValueChanged
except GetFieldNotificationDescriptor()
, which will be added by some macros. From the UWidget
example, these implement Field Notification for 3 properties:
Widget.h
UE_FIELD_NOTIFICATION_DECLARE_CLASS_DESCRIPTOR_BASE_BEGIN(UMG_API)
UE_FIELD_NOTIFICATION_DECLARE_FIELD(ToolTipText)
UE_FIELD_NOTIFICATION_DECLARE_FIELD(Visibility)
UE_FIELD_NOTIFICATION_DECLARE_FIELD(bIsEnabled)
UE_FIELD_NOTIFICATION_DECLARE_ENUM_FIELD_BEGIN(ToolTipText)
UE_FIELD_NOTIFICATION_DECLARE_ENUM_FIELD(Visibility)
UE_FIELD_NOTIFICATION_DECLARE_ENUM_FIELD(bIsEnabled)
UE_FIELD_NOTIFICATION_DECLARE_ENUM_FIELD_END()
UE_FIELD_NOTIFICATION_DECLARE_CLASS_DESCRIPTOR_BASE_END();
// Only including Visibility for the example
UPROPERTY(EditAnywhere, BlueprintReadWrite, FieldNotify, Getter, Setter, BlueprintGetter="GetVisibility", BlueprintSetter="SetVisibility", Category="Behavior")
ESlateVisibility Visibility;
Widget.cpp
void UWidget::FFieldNotificationClassDescriptor::ForEachField(const UClass* Class, TFunctionRef<bool(::UE::FieldNotification::FFieldId FielId)> Callback) const
{
for (int32 Index = 0; Index < Max_IndexOf_; ++Index)
{
if (!Callback(*AllFields[Index]))
{
return;
}
}
}
UE_FIELD_NOTIFICATION_IMPLEMENT_CLASS_DESCRIPTOR_ThreeFields(UWidget, ToolTipText, Visibility, bIsEnabled);
void UWidget::SetVisibilityInternal(ESlateVisibility InVisibility)
{
if (Visibility != InVisibility)
{
Visibility = InVisibility;
BroadcastFieldValueChanged(FFieldNotificationClassDescriptor::Visibility);
}
TSharedPtr<SWidget> SafeWidget = GetCachedWidget();
if (SafeWidget.IsValid())
{
EVisibility SlateVisibility = UWidget::ConvertSerializedVisibilityToRuntime(InVisibility);
SafeWidget->SetVisibility(SlateVisibility);
}
}
Blueprint properties on Widgets can be marked FieldNotify
as well: