UE4 C++编写自定义动画蓝图节点

news/2024/11/29 0:50:10/

UE中自带的动画蓝图节点有限,在实现一些功能时需要通过C++编写一些自定义的动画蓝图节点,本文就来讲解其基础实现,自定义节点最终效果如下:
在这里插入图片描述
源文件下载:https://download.csdn.net/download/grayrail/87654290

1.流程简介

自定义动画蓝图节点并不像扩展蓝图那样方便,需要编写AnimNodeGraphAnimNode两个类,分别负责编辑器绘制与具体执行,逻辑关系如下:
在这里插入图片描述
AnimGraphNode中存放AnimNode的字段,UE会去找对应的AnimNode,AnimNode里存放动画蓝图暴露在编辑器上的可编辑字段。

2.编写AnimGraphNode

我们使用UE4.27版本,并继承AnimNode的Skeletal中间基类,方便处理骨架逻辑。
首先来编写AnimGraphNode:


MyAnimGraphNode.h

#pragma once#include "AnimGraph/Classes/AnimGraphNode_SkeletalControlBase.h"
#include "MyAnimNode.h"
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "MyAnimGraphNode.generated.h"UCLASS(MinimalAPI)
class UMyAnimGraphNode : public UAnimGraphNode_SkeletalControlBase
{GENERATED_BODY()public:// UEdGraphNode interfacevirtual FText GetNodeTitle(ENodeTitleType::Type titleType) const override;virtual FText GetTooltipText() const override;// End of UEdGraphNode interfaceprotected:// UAnimGraphNode_SkeletalControlBase interfacevirtual FText GetControllerDescription() const override;virtual const FAnimNode_SkeletalControlBase* GetNode() const override { return &Node; }virtual void Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent* previewSkelMeshComp) const override;// End of UAnimGraphNode_SkeletalControlBase interfaceprivate:UPROPERTY(EditAnywhere, Category = Settings)FMyAnimNode Node;};

MyAnimGraphNode.cpp

#include "MyAnimGraphNode.h"
#include "Components/SkeletalMeshComponent.h"#define LOCTEXT_NAMESPACE "UMyAnimGraphNode"FText UMyAnimGraphNode::GetControllerDescription() const
{return LOCTEXT("MyAnimNodeDesc", "My Anim Node Desc");
}FText UMyAnimGraphNode::GetNodeTitle(ENodeTitleType::Type titleType) const
{return LOCTEXT("MyAnimNodeTitle", "My Anim Node Title");
}FText UMyAnimGraphNode::GetTooltipText() const
{return LOCTEXT("MyAnimNodeTooltip", "My Anim Node Tooltip");
}void UMyAnimGraphNode::Draw(FPrimitiveDrawInterface* PDI, USkeletalMeshComponent* previewSkelMeshComp) const
{}#undef LOCTEXT_NAMESPACE

上述脚本逻辑主要定义编辑器外观、颜色等信息,注意头文件上的FMyAnimNode Node字段,定义该字段才会找到对应的AnimNode。

2.编写AnimNode

该节点负责编写动画蓝图节点内的具体逻辑、暴露编辑器下的修改字段等。


MyAnimNode.h

#pragma once#include "AnimGraphRuntime/Public/BoneControllers/AnimNode_SkeletalControlBase.h"
#include "BoneContainer.h"
#include "BonePose.h"
#include "CoreMinimal.h"
#include "MyAnimNode.generated.h"USTRUCT(BlueprintInternalUseOnly)
struct MYPROJECT_API FMyAnimNode : public FAnimNode_SkeletalControlBase
{GENERATED_BODY();
public:FMyAnimNode();//输出调试信息virtual void GatherDebugData(FNodeDebugData& debugData) override;virtual bool NeedsOnInitializeAnimInstance() const override { return true; }//更新逻辑virtual void EvaluateSkeletalControl_AnyThread(FComponentSpacePoseContext& output, TArray<FBoneTransform>& outBoneTransforms) override;//验证是否可以执行更新逻辑virtual bool IsValidToEvaluate(const USkeleton* skeleton, const FBoneContainer& requiredBones) override;private://初始化骨骼时调用virtual void InitializeBoneReferences(const FBoneContainer& requiredBones) override;UPROPERTY(EditAnywhere)FBoneReference TargetBone;
};

MyAnimNode.cpp

#include "MyAnimNode.h"
#include "Animation/AnimInstanceProxy.h"
#include "AnimationCoreLibrary.h"
#include "AnimationRuntime.h"FMyAnimNode::FMyAnimNode()
{
}void FMyAnimNode::GatherDebugData(FNodeDebugData& debugData)
{FString DebugLine = debugData.GetNodeName(this);DebugLine += "(";AddDebugNodeData(DebugLine);DebugLine += FString::Printf(TEXT(")"));debugData.AddDebugItem(DebugLine);ComponentPose.GatherDebugData(debugData);
}void FMyAnimNode::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseContext& output,TArray<FBoneTransform>& outBoneTransforms)
{check(outBoneTransforms.Num() == 0);const FBoneContainer& boneContainer = output.Pose.GetPose().GetBoneContainer();const FCompactPoseBoneIndex boneCPB = TargetBone.GetCompactPoseIndex(boneContainer);if (boneCPB == INDEX_NONE) return;FTransform boneTransform = output.Pose.GetComponentSpaceTransform(boneCPB);boneTransform.SetScale3D(FVector::ZeroVector);outBoneTransforms.Add(FBoneTransform(boneCPB, boneTransform));outBoneTransforms.Sort(FCompareBoneTransformIndex());
}bool FMyAnimNode::IsValidToEvaluate(const USkeleton* skeleton, const FBoneContainer& requiredBones)
{if (TargetBone.IsValidToEvaluate()) return true;return false;
}void FMyAnimNode::InitializeBoneReferences(const FBoneContainer& requiredBones)
{TargetBone.Initialize(requiredBones);
}

3.配置build.cs

依赖项参考了其他动画蓝图节点的配置,可能有冗余:

using UnrealBuildTool;public class MyProject : ModuleRules
{public MyProject(ReadOnlyTargetRules Target) : base(Target){PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;PublicDependencyModuleNames.AddRange(new string[]{"Core","CoreUObject","Engine","InputCore","HeadMountedDisplay","AnimGraph","AnimGraphRuntime","BlueprintGraph"});}
}

最后编译即可。
上述节点执行后将对选中的骨骼,设置缩放为0。


http://www.ppmy.cn/news/39224.html

相关文章

【华为OD机试真题】猜字谜(javapython)

猜字谜 时间限制:1s空间限制:256MB 限定浯言:不限 题目描述: 小王设计了一个简单的猜字谜游戏,游戏的谜面是一个错误的单词,比如nesw,玩 家需要猜出谜底库中正确的单词。猜中的要求如下: 对于某个谜面和谜底单词,满足下面任一条件都表示猜中: 变换顺序以后一样的,…

mac电脑配置adb

1、打开mac的terminal终端&#xff0c;输入 cd ~/ 2、输入 touch .bash_profile&#xff0c;如果没有.bash_profile这个文件&#xff0c;则创建一个这个文件 3、输入 open .bash_profile &#xff0c;打开创建的.bash_profile 文件&#xff0c;此时应该弹出一个文本编辑框&am…

【问题解决】glob.glob 如何匹配所有子文件夹下的文件 —— recursive=True

一、仅匹配一级目录下的文件 import glob label_dir /data/part1/dir1/*.txt datas glob.glob(label_dir) print(datas) >>> [/data/part1/dir1/001.txt, /data/part1/dir1/002.txt]二、匹配多级文件夹下的文件 glob 模块在 python3.5 之后就支持了匹配所有子文件…

JavaSE基础(18) 继承

继承 概念 生活中我们经常听到一些名词&#xff0c;譬如富二代&#xff0c;官二代&#xff0c;红二代&#xff0c;穷二代&#xff0c;农二代等等&#xff0c;它代表中人与人之间的一种关系。那么程序当中怎么表示这种关系呢&#xff1f; 概念&#xff1a;描述两个类的关系的…

操作系统的概念、功能、目标

1.操作系统的层次结构 2.操作系统的概念 负责管理协调硬件和软件等计算机资源的操作 为上层的应用系统、用户提供简单易用的服务 操作系统是系统软件&#xff0c;而不是硬件 3.操作系统的功能与目标 先放一张思维导图&#xff0c;大概知道操作系统的具体功能和目标&#x…

企业敏感数据保护

数据风险评估 组织经常处理大量敏感数据;例如&#xff0c;医疗保健组织处理大量敏感的患者信息。如果未存储在安全位置&#xff0c;攻击者可能会利用此信息。 数据风险评估是指评估组织关键数据的存储位置的过程。它涉及根据文件的敏感性对文件进行分类并为它们提供必要的安全…

Qt配置Libtorch并简单测试

文章目录软件版本一、下载Libtorch二、配置Qt Creator三、测试项目参考&#xff1a;纯小白初次学习深度学习&#xff0c;根据目前所学、所查资料总结该配置文章&#xff0c;如有更好的方法将深度学习模型通过C部署到实际工程中&#xff0c;希望学习交流。 软件版本 Python3.1…

推箱子小游戏

文章目录一、 介绍二、 制作墙壁、地面三、 制作箱子四、 制作终点五、 制作人物移动六、 推箱子关键触发机制七、 终点设置八、 关卡切换设置九、 协程十、 下载一、 介绍 2D推箱子游戏是一种益智类游戏&#xff0c;玩家需要控制角色将箱子推到指定的位置&#xff0c;以完成关…