Skip to main content
 首页 » 资源教程 » UE4教程

[UE4]CustomAnimationBlueprintNode 自定义动画蓝图节点

2016年09月14日 20:36:548740

目的:在AnimationBlueprint中使用自定义动画控制节点。

主要过程:

1.      引用相关模块。在Client.Build.cs文件中,PublicDependencyModuleNames.AddRange里加入”AnimGraphRuntime”,“AnimGraph”, “BlueprintGraph”,添加引用模块后可在使用时直接包含头文件名称,而不用指定具体路径。

2.      实现AnimNode类,用于处理更新骨骼位置等具体逻辑;

3.      实现AnimGraphNode类,用于在编辑器中显示信息等;

4.      编辑工程后即可在AnimationBlueprint中使用该节点


下面以我的自定义动画节点CopyParentBone为例,该节点作用是更改当前Component内某骨骼的Transform为Parent Component内同名称骨骼的Transform:

 

一、添加引用模块

Client.Build.cs

  1. PublicDependencyModuleNames.AddRange(new string[]   
  2.         {   
  3.             "Core",   
  4.             "CoreUObject",   
  5.             "Engine",   
  6.             "InputCore",  
  7.             "AIModule",  
  8.             "GameplayTasks",  
  9.             "Landscape",  
  10.             "Foliage",  
  11.             "AnimGraphRuntime",  
  12.             "AnimGraph",  
  13.             "BlueprintGraph"  
  14.         });  


二、AnimNode类

Public/AnimNode_CopyParentBone.h


  1. /* 
  2.  * \file AnimNode_CopyParentBone.h 
  3.  * 
  4.  * \author: Jia Zhipeng 
  5.  * \date: 2016/02/24  
  6.  */  
  7.   
  8. #pragma once  
  9. #include "AnimNode_SkeletalControlBase.h"  
  10. #include "AnimNode_CopyParentBone.generated.h"  
  11.   
  12. USTRUCT()  
  13. struct FAnimNode_CopyParentBone :public FAnimNode_SkeletalControlBase  
  14. //父类可以是FAnimNode_SkeletalControlBase或者FAnimNode_Base  
  15. //FAnimNode_SkeletalControlBase一般用于对骨骼的控制,通过EvaluateBoneTransforms更改骨骼位置。  
  16. //FAnimNode_Base一般用于对整体MeshBase的更改,通过Evaluate或者EvaluateComponentSpace更改Output.Pose更改全身的位置  
  17. //自定义类继承父类后,override部分接口即可,以下是我用到的主要接口  
  18. {  
  19.     GENERATED_USTRUCT_BODY()  
  20.   
  21.     /** Name of bone to control. **/  
  22.     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SkeletalControl)  
  23.     FBoneReference BoneToModify;  
  24.       
  25. public:  
  26.     //  Constructor  
  27.     FAnimNode_CopyParentBone();  
  28.   
  29. //  // FAnimNode_Base interface  
  30. //  显示Debug信息  
  31.     virtual void GatherDebugData(FNodeDebugData& DebugData) override;  
  32. //  // End of FAnimNode_Base interface  
  33.   
  34.     // FAnimNode_SkeletalControlBase interface  
  35. //  更改位置的逻辑实现函数  
  36.     virtual void EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms) override;  
  37. //  判断用到的骨骼是否有效   
  38. virtual bool IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones) override;  
  39.     // End of FAnimNode_SkeletalControlBase interface  
  40.   
  41. private:  
  42.     // FAnimNode_SkeletalControlBase interface  
  43. //  初始化骨骼引用  
  44.     virtual void InitializeBoneReferences(const FBoneContainer& RequiredBones) override;  
  45.     // End of FAnimNode_SkeletalControlBase interface  
  46. };  


Private/AnimNode_CopyParentBone.cpp

  1. /* 
  2.  * \file AnimNode_CopyParentBone.cpp 
  3.  * 
  4.  * \author: Jia Zhipeng 
  5.  * \date: 2016/02/24  
  6.  */  
  7.   
  8. #include "Client.h"//自己的Game.h  
  9. #include "AnimNode_CopyParentBone.h"  
  10.   
  11. FAnimNode_CopyParentBone::FAnimNode_CopyParentBone()  
  12. {  
  13.       
  14. }  
  15.   
  16. //控制骨骼运动的逻辑实现。在OutBoneTransforms里Add需要修改的BoneTransform  
  17. void FAnimNode_CopyParentBone::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms)  
  18. {  
  19.     check(OutBoneTransforms.Num() == 0);  
  20.     FTransform NewBoneTM = FTransform::Identity;  
  21.     const FBoneContainer BoneContainer = MeshBases.GetPose().GetBoneContainer();  
  22.       
  23.     USceneComponent* ParentComponent = SkelComp->GetAttachParent();  
  24.     if (ParentComponent)  
  25.         NewBoneTM = ParentComponent->GetSocketTransform(BoneToModify.BoneName, RTS_Component);  
  26.     else  
  27.     {  
  28.         UE_LOG(LogAnimation, Warning, TEXT("FAnimNode_CopyParentBone cannot get parent component"));  
  29.     }  
  30.     OutBoneTransforms.Add(FBoneTransform(BoneToModify.GetCompactPoseIndex(BoneContainer), NewBoneTM));  
  31. }  
  32.   
  33. void FAnimNode_CopyParentBone::GatherDebugData(FNodeDebugData& DebugData)  
  34. {  
  35.     FString DebugLine = DebugData.GetNodeName(this);  
  36.   
  37.     DebugLine += "(";  
  38.     AddDebugNodeData(DebugLine);  
  39.     DebugLine += FString::Printf(TEXT(" Target: %s)"), * BoneToModify.BoneName.ToString());  
  40.     DebugData.AddDebugItem(DebugLine);  
  41.   
  42.     ComponentPose.GatherDebugData(DebugData);  
  43. }  
  44.   
  45. bool FAnimNode_CopyParentBone::IsValidToEvaluate(const USkeleton* Skeleton, const FBoneContainer& RequiredBones)  
  46. {  
  47.     return (BoneToModify.IsValid(RequiredBones));  
  48. }  
  49.   
  50. void FAnimNode_CopyParentBone::InitializeBoneReferences(const FBoneContainer& RequiredBones)  
  51. {  
  52.     BoneToModify.Initialize(RequiredBones);  
  53. }  


三、AnimGraphNode

Public/AnimGraphNode_CopyParentBone.h

  1. /* 
  2.  * \file AnimGraphNode_CopyParentBone.h 
  3.  * 
  4.  * \author: Jia Zhipeng 
  5.  * \date: 2016/02/24 
  6.  * \purporse: 自定义动画节点,在Parent Component中获得与当前Component的根骨骼同名的骨骼Transform,然后设置为当前骨骼的Transform 
  7.  */  
  8. #pragma once  
  9. #include "AnimGraphNode_SkeletalControlBase.h"  
  10. #include "AnimNode_CopyParentBone.h"  
  11. #include "AnimGraphNode_CopyParentBone.generated.h"  
  12.   
  13. UCLASS(MinimalAPI)  
  14. class UAnimGraphNode_CopyParentBone : public UAnimGraphNode_SkeletalControlBase  
  15. {  
  16.     GENERATED_UCLASS_BODY()  
  17.   
  18.     UPROPERTY(EditAnywhere, Category=Settings)  
  19.     FAnimNode_CopyParentBone Node;  
  20.   
  21.     // UEdGraphNode interface  
  22. //  鼠标悬浮在Node上的提示文本  
  23.     virtual FText GetTooltipText() const override;  
  24. //  Node的名字文本     
  25. virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;  
  26.     // End of UEdGraphNode interface  
  27.   
  28. protected:  
  29.     // UAnimGraphNode_SkeletalControlBase interface  
  30. //  返回controller的描述  
  31.     virtual FText GetControllerDescription() const override;  
  32. //  返回引用的AnimNode  
  33.     virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }  
  34.     // End of UAnimGraphNode_SkeletalControlBase interface  
  35.       
  36. };  

Private/AnimGraphNode_CopyParenBone.cpp

  1. /* 
  2.  * \file AnimNode_CopyParentBone.cpp 
  3.  * 
  4.  * \author: Jia Zhipeng 
  5.  * \date: 2016/02/24  
  6.  */  
  7.   
  8. #include "Client.h"  
  9. #include "AnimGraphNode_CopyParentBone.h"  
  10.   
  11. #define LOCTEXT_NAMESPACE "A3Nodes"  
  12. UAnimGraphNode_CopyParentBone::UAnimGraphNode_CopyParentBone(const FObjectInitializer& ObjectInitializer)  
  13. :Super(ObjectInitializer)  
  14. {  
  15. }  
  16.   
  17. FText UAnimGraphNode_CopyParentBone::GetTooltipText() const  
  18. {  
  19.     return LOCTEXT("AnimGraphNode_CopyParentBone_Tooltip""Copy parent bone's transform to this component's root. Their names must be same");  
  20. }  
  21.   
  22. FText UAnimGraphNode_CopyParentBone::GetNodeTitle(ENodeTitleType::Type TitleType) const  
  23. {  
  24.     return LOCTEXT("AnimGraphNode_CopyParentBone_Title""Copy Parent Bone");  
  25. }  
  26.   
  27. FText UAnimGraphNode_CopyParentBone::GetControllerDescription() const  
  28. {  
  29.     return LOCTEXT("CopyParentBone""Copy Parent Bone");  
  30. }  
  31.   
  32. #undef LOCTEXT_NAMESPACE  


参考内容

1.Animation Node, Entire Source for a TurnIn Place Node

https://wiki.unrealengine.com/Animation_Node,_Entire_Source_for_a_Turn_In_Place_Node

2. 创建自定义动画节点

https://www.unrealengine.com/zh-CN/blog/creating-custom-animation-nodes

3.UE引擎中部分节点如AnimNode_CopyBone,AnimNode_ModifyBone的源代码

评论列表暂无评论
发表评论