Context: I used Livelink for Blender plugin to send data frame-by-frame from Blender to UE5. The node BlenderUnreal Livelink appears in AnimGraph as below
Problem statement: I want to custom this node so that it produces 4 output pins. In the code, the struct FRGBRokokoAnimNode
(RGBRokokoAnimNode.h) and the class UFRGBRokokoAnimGraphNode
(FRGBRokokoAnimGraphNode.h) are, I guess, mainly responsible for the node interface in the AnimGraph, with the former reading & processing data from Blender.
This is the struct declaration
USTRUCT()
struct RGBPOSELIVELINK_API FRGBRokokoAnimNode : public FAnimNode_SkeletalControlBase
{
GENERATED_USTRUCT_BODY()UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = RGBSkeletalControl, meta = (PinShownByDefault))
FName RGBMocapActorName;UPROPERTY(EditAnywhere, Category = RGBSkeletalControl)
URGBRokokoBoneMap* BoneMapOverride;//For bone rotations
TMap<FName, float> LiveLinkCurvesCpp;float ScaleFactor;
FVector NormalizedForward;
FVector GetVectorFromCurvesCpp(const FString BoneName);
FVector CalculateNormalCpp(const FVector A, const FVector B, const FVector C);float CalculateHeightCpp();
FTransform GetTransformFromCurvesCpp(const FString BoneName);
float CalculateScaleFactorCpp(float ManequinHeight, float HeightFromSolver);
void TranslationMethodCpp();
void RotationMethodCpp(TMap<FName, FTransform>& sourceBoneFinalTransforms);
FTransform CalcTransformForRotation(const FString FirstBone, const FString SecondBone, const bool useXZ = false, const bool invertForward = false);TArray BoneReferencesArray;
bool firstTime;
TArray CopyOfOutBoneTransforms;//Bone References;
FBoneReference rShldrBend;
FBoneReference rForearmBend;
FBoneReference rHand;
FBoneReference lShldrBend;
FBoneReference lForearmBend;
FBoneReference lHand;
FBoneReference rThighBend;
FBoneReference rShin;
FBoneReference rFoot;
FBoneReference lThighBend;
FBoneReference lShin;
FBoneReference lFoot;
FBoneReference abdomenUpper;
FBoneReference hip;
FBoneReference head;
FBoneReference neck;
FBoneReference spine;void ApplyBoneRotation(TMap<FName, FTransform> sourceBoneFinalTransforms , FName boneName, FBoneReference boneReference, FCSPose& MeshBases);
void ApplyBonePosition(TMap<FName, FTransform> sourceBoneFinalTransforms , FName boneName, FBoneReference boneReference, FCSPose& MeshBases);
public:// Constructor
FRGBRokokoAnimNode();UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = “foot contact”, meta = (PinShownByDefault))
float footContact;UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = “Test”, meta = (PinShownByDefault))
UTestAnimNode* TestPtr;// FAnimNode_Base interface
// Display Debug Information
virtual void GatherDebugData(FNodeDebugData& DebugData) override;// FAnimNode_SkeletalControlBase interface
// Change the position of the logic functions to achieve
virtual void EvaluateSkeletalControl_AnyThread(FComponentSpacePoseContext& Output, TArray& OutBoneTransforms) override;
// used to determine the effectiveness of bone
virtual bool IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones) override;virtual bool HasPreUpdate() const { return true; }
virtual void PreUpdate(const UAnimInstance* InAnimInstance) override;FLiveLinkSubjectName GetLiveLinkSubjectName();
private:
// FAnimNode_SkeletalControlBase interface
// Initialize the bones references
virtual void InitializeBoneReferences(const FBoneContainer& RequiredBones) override;
// End of FAnimNode_SkeletalControlBase interfaceFLiveLinkClientReference LiveLinkClient_GameThread;
ILiveLinkClient* LiveLinkClient_AnyThread;
};
This is the class declaration
UCLASS()
class RGBPOSELIVELINK_API UFRGBRokokoAnimGraphNode : public UAnimGraphNode_SkeletalControlBase
{
GENERATED_UCLASS_BODY()//GT
UPROPERTY(EditAnywhere, Category = Settings)
FRGBRokokoAnimNode Node;
//TEST
//UPROPERTY(EditAnywhere, Category = Settings)
// UTestAnimNode* Node;// UEdGraphNode interface
// mouse over Node prompt text
virtual FText GetTooltipText() const override;
// Node name text
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
// End of UEdGraphNode interfaceprotected:
// UAnimGraphNode_SkeletalControlBase interface
// returns the controller description
virtual FText GetControllerDescription() const override;// returns AnimNode cited
// GT
virtual const FAnimNode_SkeletalControlBase* GetNode() const override {
return &Node;
}
// TEST
//virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }
};
Solution experiments: I attempted to create 1 output pin first and later broadcast to 4 output pins
-
As I understand, to create a custom output pin, UFUNCTION() is needed but it can’t be declared under USTRUCT() scope and therefore not suitable to put it in the FRGBRokokoAnimNode struct, I tried to put it in the class UFRGBRokokoAnimGraphNode but after I compiled successfully, the output pin is still invisible in the node
-
Intermidiate class: I created an intermidiate class to be able to use UFUNCTION(), this class is later included in the struct and class mentioned as a pointer type so that I can call to the UFUNCTION(). But the result is the input pin TestPtr in the image above instead of the output pin.
Set up (in both Blender and UE5): To install and experiment with the plugin, please see the instructions here
I have read other similar questions but found no solutions (I’m a beginner and can miss out some important things ). Thanks for your time.