I am trying to build some custom AnimGraph nodes. I have gotten them to compile and run, but have had some issues when using them in my Blueprints. When I create custom UPROPERTYs on the node and connect to them using Blueprints, the values do not get to the c++. When querying the property, I get the default value specified at construction time.
I have created a very simple node to demonstrate what I’m talking about. On it there is a float UPROPERTY called TestAttr. In the various functions, I print the value of TestAttr to the log. When I create this node in a Blueprint and connect an input to TestAttr, I don’t get the values, though they show in the editor when hovering over the connection.
Can someone please tell me what I’m doing wrong?
Here’s the code:
AnimNode_TestNode.h
#pragma once
#include "Animation/AnimNodeBase.h"
#include "AnimInstanceProxy.h"
#include "AnimNode_TestNode.generated.h"
USTRUCT()
struct FAnimNode_TestNode : public FAnimNode_Base
{
GENERATED_USTRUCT_BODY()
// Input Pose
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Links)
FPoseLink Pose;
// Test Attribute
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Settings, meta = (PinShownByDefault))
mutable float TestAttr;
FAnimNode_TestNode();
// FAnimNode_Base interface
virtual void GatherDebugData(FNodeDebugData& DebugData) final;
virtual void Initialize(const FAnimationInitializeContext& Context) final;
virtual void CacheBones(const FAnimationCacheBonesContext& Context) final;
virtual void Update(const FAnimationUpdateContext& Context) final;
virtual void Evaluate(FPoseContext& Output) final;
// End of FAnimNode_Base interface
};
AnimNode_TestNode.cpp
#include "dDNAToolsPrivatePCH.h"
#include "AnimNode_TestNode.h"
#include "AnimationRuntime.h"
#include "AnimInstanceProxy.h"
/////////////////////////////////////////////////////
// TestNode
FAnimNode_TestNode::FAnimNode_TestNode()
: FAnimNode_Base(),
TestAttr(0.0f)
{
UE_LOG(LogTemp, Error, TEXT("Constructor: %f"), TestAttr);
}
void FAnimNode_TestNode::GatherDebugData(FNodeDebugData& DebugData)
{
FString DebugLine = DebugData.GetNodeName(this);
DebugData.AddDebugItem(DebugLine);
}
void FAnimNode_TestNode::Initialize(const FAnimationInitializeContext& Context)
{
FAnimNode_Base::Initialize(Context);
Pose.Initialize(Context);
UE_LOG(LogTemp, Warning, TEXT("Initialize: %f"), TestAttr);
}
void FAnimNode_TestNode::CacheBones(const FAnimationCacheBonesContext& Context)
{
FAnimNode_Base::CacheBones(Context);
Pose.CacheBones(Context);
UE_LOG(LogTemp, Warning, TEXT("Cache: %f"), TestAttr);
}
void FAnimNode_TestNode::Update(const FAnimationUpdateContext& Context)
{
FAnimNode_Base::Update(Context);
Pose.Update(Context);
UE_LOG(LogTemp, Warning, TEXT("Update: %f"), TestAttr);
}
void FAnimNode_TestNode::Evaluate(FPoseContext& Output)
{
UE_LOG(LogTemp, Warning, TEXT("Evaluate: %f"), TestAttr);
Pose.Evaluate(Output);
UE_LOG(LogTemp, Warning, TEXT("Evaluate End: %f"), TestAttr);
}
AnimGraphNode_TestNode.h
#pragma once
#include "AnimGraphNode_Base.h"
#include "AnimNode_TestNode.h"
#include "AnimGraphNode_TestNode.generated.h"
UCLASS()
class UAnimGraphNode_TestNode : public UAnimGraphNode_Base
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category = Settings)
FAnimNode_TestNode Node;
public:
// UEdGraphNode Interface
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const final;
virtual FText GetTooltipText() const final;
virtual FLinearColor GetNodeTitleColor() const final;
virtual FString GetNodeCategory() const final;
virtual void CreateOutputPins() final;
// End of UEdGraphNode Interface
protected:
virtual FString GetControllerDescription() const { return FString(); }
};
AnimGraphNode_TestNode.cpp
#include "dDNAToolsEditorPCH.h"
#include "AnimGraphNode_TestNode.h"
#include "AnimationGraphSchema.h"
UAnimGraphNode_TestNode::UAnimGraphNode_TestNode(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{ }
FLinearColor UAnimGraphNode_TestNode::GetNodeTitleColor() const
{
return FLinearColor(0, 12, 12, 1);
}
FText UAnimGraphNode_TestNode::GetTooltipText() const
{
return FText::FromString("Test Node");
}
FString UAnimGraphNode_TestNode::GetNodeCategory() const
{
return FString("Testing");
}
FText UAnimGraphNode_TestNode::GetNodeTitle(ENodeTitleType::Type TitleType) const
{
return FText::FromString(GetControllerDescription());
}
//Node Output Pin (Change at own RISK!)
void UAnimGraphNode_TestNode::CreateOutputPins()
{
const UAnimationGraphSchema* Schema = GetDefault<UAnimationGraphSchema>();
CreatePin(EGPD_Output, Schema->PC_Struct, TEXT(""), FPoseLink::StaticStruct(), /*bIsArray=*/ false, /*bIsReference=*/ false, TEXT("OutputPose"));
}