Download

Data connection for additional Output Pin with custom AnimNode

I’m currently working on a custom AnimNode where I would like to output a secondary data in addition to the pose in the animation graph of my AnimBlueprint. I found the way to add that secondary output pin, but I have no idea how to connect it to the actual data within the base node.

I build the output pin with CreatePin(), but I don’t really understand how the data is assigned, especially since in the case of the output pose it seems automatic.

I already gave a look at the source of existing nodes, but none of them do this kind of behavior. So for now I’m a bit stuck.

animnode.png

Below is is some sample code.

AnimNode_GetBoneTransform.h


USTRUCT(BlueprintType)
struct FAnimNode_GetBoneTransform : public FAnimNode_Base
{
    GENERATED_USTRUCT_BODY()

    public:
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Links)
        FPoseLink BasePose;

        UPROPERTY(EditAnywhere, Category = Settings, meta = (PinHiddenByDefault))
        FBoneReference Bone;

        FVector BoneLocation;


        // FAnimNode_Base interface
        virtual void Initialize_AnyThread(const FAnimationInitializeContext& Context) override;
        virtual void Update_AnyThread(const FAnimationUpdateContext& Context) override;
        virtual void Evaluate_AnyThread(FPoseContext& Output) override;
        virtual void CacheBones_AnyThread(const FAnimationCacheBonesContext& Context) override;

        /*
        virtual void GatherDebugData(FNodeDebugData& DebugData) override;
        // End of FAnimNode_Base interface
        */

        FAnimNode_GetBoneTransform();

    private:
        USkeletalMeshComponent* SkeletalMesh;
};

AnimGraphNode_GetBoneTransform.h


UCLASS(MinimalAPI)
class UAnimGraphNode_GetBoneTransform : public UAnimGraphNode_Base
{
    GENERATED_UCLASS_BODY()

    UPROPERTY(EditAnywhere, Category = SkeletalControl)
    FAnimNode_GetBoneTransform Node;

    public:
        //Begin UEdGraphNode Interface.
        virtual FLinearColor GetNodeTitleColor() const override;
        virtual FText GetTooltipText() const override;
        virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
        //End UEdGraphNode Interface.

        //Begin UAnimGraphNode_Base Interface
        virtual FString GetNodeCategory() const override;
        //End UAnimGraphNode_Base Interface

    protected:
        // UAnimGraphNode_Base interface
        virtual void ValidateAnimNodeDuringCompilation(USkeleton* ForSkeleton, FCompilerResultsLog& MessageLog) override;
        virtual void CopyNodeDataToPreviewNode(FAnimNode_Base* InPreviewNode) override;
        virtual void CopyPinDefaultsToNodeData(UEdGraphPin* InPin) override;
        // End of UAnimGraphNode_Base interface


    private:
        virtual void CreateOutputPins() override;

};

Excerpt of AnimGraphNode_GetBoneTransform.cpp


void UAnimGraphNode_GetBoneTransform::CreateOutputPins()
{
    const UAnimationGraphSchema* Schema = GetDefault<UAnimationGraphSchema>();

    CreatePin(EGPD_Output, Schema->PC_Struct, FPoseLink::StaticStruct(), TEXT("Pose"));

    CreatePin(EGPD_Output, Schema->PC_Struct, TBaseStructure<FVector>::Get(), TEXT("Bone Location"));
}

I recently got an answer from Lina Halper from Epic Games who confirmed it wasn’t possible. She however suggested another approach, so I’m pasting her reply here:

So, I went an other route in the end. I simply worked around the issue by using my head and root bones as reference point to drive my IK and Transform nodes.