Exposing FoldProperty pins in AnimGraph nodes

I’ve run into a pretty tricky issue when trying to modify the AnimNode_Mirror K2 node. I have a use case where we want to dynamically set the MirrorDataTable node. So initially, I exposed the variable as a pin like in the code snippet attached.

This didn’t end up working as the value kept getting stomped, which after some investigation I’ve discovered is an intentional function of values marked as FoldProperty. For now I do have a workaround, I’ve created a separate proxy pin that isn’t a FoldProperty to plug the MirrorDataTable into and that seems to be working fine for now. But I’m curious to hear if there are better approaches or if I’ve misunderstood the Animation Blueprint compiler internals.

UPROPERTY(EditAnywhere, Category = Settings, meta = (FoldProperty, PinShownByDefault)) TObjectPtr<UMirrorDataTable> MirrorDataTable = nullptr;

Hi,

What do you mean when you state “the value kept getting stomped”? Just adding the PinShownByDefault metadata as you have here should be all you need to get this updated dynamically based around pin-input (as it already is updated dynamically via FAnimNode_Mirror::SetMirrorDataTable).

For some background, FoldProperty is there to inform the compiler that values that are constants can be folded into a single value shared by multiple nodes. This memory optimization is only used at runtime, not edit time (FoldProperty pins need to be WITH_EDITORONLY_DATA). If a FoldProperty pin has a dynamic/pinned value, then it will not be folded into constants, instead it will use a generated property of the classes ‘mutables’ structure as a proxy value (accessed via the GET_ANIM_NODE_DATA (etc.) macros).

That reference is not responsible for dynamic (pin-accessed) values, that would only be used by the compiler in the case of a constant value for the pin.

Hello,

That was my impression as well but upon recompilation it would error out saying the MirrorDataTable variable is not set even if it clearly is connected to the pin. After attaching a data breakpoint, I found that at the part of the code below it is getting set to null on compilation when the editor is started back up again and I open the blueprint. The function below is FAnimBlueprintNodeOptionalPinManager::PostInitNewPin

// Clear the asset reference on the node if the pin exists // In theory this is only needed for pins that are newly created but there are a lot of existing nodes that have dead asset references FObjectProperty* ObjectProperty = CastField<FObjectProperty>(Property); if (ObjectProperty) { ObjectProperty->SetObjectPropertyValue(PropertyAddress, nullptr); }