Introduction
What Is Save&Use Cached Pose Node?
UE4 has already provided a Save Cached Pose for one-to-many link in Anim Graph like this:

We can use a Use Save Cached Pose node to refer a Save Cached Pose node.

Not-recommended Way
It actually surprised me that we can use Reroute Node to achieve one to many pose link like this:

And it does work.
However, I’ve talked to Epic about this issue and it turned out that this is considered as a bug. Moreover, this could cause multiple evaluation&update, which might result in some strange issue.
In short, just don’t use it.
What’s Deep Inside ?
Let’s take a look at function FAnimNode_SaveCachedPose::Evaluate_AnyThread
1 | void FAnimNode_SaveCachedPose::Evaluate_AnyThread(FPoseContext& Output) |
It is guaranteed to have referred nodes to be evaluated at most once per frame by synchronizing evaluation counters. And this is truly useful when building complex animation blueprints.
The Sadness of Space-Conversion
This method only works, however, in Local Spaces.
This means that we need extra some space transform nodes if we want to achieve one-to-many pose link in component space like this:

Space convert node is not that cheap since every bone is required to perform a space conversion.
Thus we made some modification to use cached pose and save cached pose node.
Modification Details
FAnimNode_SaveCachedPose and UAnimGraphNode_SaveCachedPose
Add a FComponentSpacePoseLink to FAnimNode_SaveCachedPose, and of course, a boolean property to determine if this node is under component space or local space.
Moreover, a FCSPose<FCompactPose> property is also needed. Because a FCompactPose does not have ComponentSpaceFlags, which is supposed to be passed from Save cahced pose node to Use cached pose node.
Obviously we need to override EvaluateComponentSpace_AnyThread function, which is simply the same as Evaluate_AnyThread.
1 | void FAnimNode_SaveCachedPose::EvaluateComponentSpace_AnyThread(FComponentSpacePoseContext& Output) |
Of course, don’t forget to handle CacheBones_AnyThread, Initialize_AnyThread and PostGraphUpdate function.
As for UAnimGraphNode_SaveCachedPose, we need to override its CustomizePinData and PostEditChangeProperty function:
1 | void UAnimGraphNode_SaveCachedPose::CustomizePinData(UEdGraphPin* Pin, FName SourcePropertyName, int32 ArrayIndex) const |
FAnimNode_UseCachedPose and UAnimGraphNode_UseCachedPose
First of all, we should add a FComponentSpacePoseLink property, just like LinkToCachingNode.
Then override EvaluateComponentSpace_AnyThread function that simply evaluate the component space pose link.
Still, we need to override CreateOutputPins function to eventually create component space out pins.
1 | void UAnimGraphNode_UseCachedPose::CreateOutputPins() |
Link Pose Together
We need to link FAnimNode_UseCachedPose::LinkToCachingNode_Component to FAnimNode_SaveCachedPose::ComponentPose.
To achieve this, we should modify FAnimBlueprintCompilerContext::ProcessUseCachedPose function
1 | if (UAnimGraphNode_SaveCachedPose* AssociatedSaveNode = SaveCachedPoseNodes.FindRef(UseCachedPose->SaveCachedPoseNode->CacheName)) |
Last but not least, we should handle such warning:

In order to solve this issue, we should modify FAnimBlueprintCompilerContext::ProcessAnimationNode function:
1 | if (!bConsumed && (SourcePin->Direction == EGPD_Input)) |
And that’s all! Everything is good to go:

Enjoy this feature.