UE4 创建自定义动画节点
创建自定义动画节点需要两个类:
一个是您在编辑器中看到的图表节点
一个是真正在运行时工作的行为节点
动画图表节点,派生自:UAnimGraphNode_Base
例如:class UAnimGraphNode_SequencePlayer : public UAnimGraphNode_Base
动画行为节点,派生自:FAnimNode_Base
例如:struct ENGINE_API FAnimNode_SequencePlayer : public FAnimNode_Base
两个节点的基类是不同的:一个基类是UObject(UAnimGraphNode_Base),另一个的基类是UStruct(FAnimNode_Base)
动画图表节点类的构建:
所有的图表节点包含了类似这样的对应行为节点:
class UAnimGraphNode_SequencePlayer : public UAnimGraphNode_Base
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, Category=Settings)
FAnimNode_SequencePlayer Node;
}
这就是最简单的 动画图表节点,其中包含动作行为节点对象。
动画行为节点的执行,是通过FPoseLink或FComponentSpacePoseLink进行串联的。
FPoseLink 是本地骨骼空间的(其实是相对于父节点来说的), FComponetSpacePoseLink是控件空间的。
动画图表节点默认带有FPoseLink输出(也就是右侧的小人), 如果需要改变成FComponetSpacePoseLink, 需要重写CreateOutputPins,其中调用CreatePin。
virtual void CreateOutputPins() override;
void UAnimGraphNode_LocalToComponentSpace::CreateOutputPins()
{
CreatePin(EGPD_Output, UAnimationGraphSchema::PC_Struct, FComponentSpacePoseLink::StaticStruct(), TEXT("ComponentPose"));
}
动画行为节点类的构建
让我们看下FAnimNode_Base节点:
struct ENGINE_API FAnimNode_Base
{
// Interface to implement,这就是你在你的动画行为节点中应该重写的几个函数
virtual void Initialize_AnyThread(const FAnimationInitializeContext& Context) {}
virtual void Update_AnyThread(const FAnimationUpdateContext& Context) {}
virtual void Evaluate_AnyThread(FPoseContext& Output) { check(false); }
virtual void EvaluateComponentSpace_AnyThread(FComponentSpacePoseContext& Output) { check(false); }
virtual void CacheBones_AnyThread(const FAnimationCacheBonesContext& Context) {}
virtual void GatherDebugData(FNodeDebugData& DebugData){}
};
有三个决定了您的节点如何表现的主要函数。它们是Initialize_AnyThread、Update_AnyThread和Evaluate_AnyThread,这里是对它们应用的简单描述:
Initialize_AnyThread - 任何时候当您需要进行初始化或重新初始化时调用该函数(当修改实例的网格物体时)。
Update_AnyThread - 调用该函数来更新当前状态(比如更新播放时间或混合权重)。该函数取入一个FAnimationUpdateContext,它知道更新的DeltaTime和当前的节点混合权重。
Evaluate_AnyThread - 调用该函数来生成一个‘姿势’(一系列的骨骼变换)。//当动画图表节点的输出是FPoseLink时,执行的是该函数, 如果是FComponetSpacePoseLink,执行的应该是EvaluateComponentSpace_AnyThread
EvaluateComponentSpace_AnyThread- 调用该函数来生成一个‘姿势’(一系列的骨骼变换)
最重要的就是Evaluate_AnyThread和EvaluateComponentSpace_AnyThread,其中最终的操作是骨骼变换的设置。
void FAnimNode_MYAnimNode::Evaluate_AnyThread(FPoseContext & Output){FName BoneName(TEXT("boneName"));//Output.Pose.GetBoneContainer()返回的FBoneContainer中,包含有当前网格体用到的骨架的引用,以及当前网格体用到的骨架中的真正用到的骨骼的索引数组。索引数组包含骨架的部分或全部。//OutPut.Pose中包含用到的骨骼的变换数组,骨骼变换数组与FBoneContainer中的索引数组相互对应。//GetPoseBoneIndexForBoneName是根据骨骼名称,获取骨骼的索引int32 MeshIndex = Output.Pose.GetBoneContainer().GetPoseBoneIndexForBoneName(BoneName);if (MeshIndex != INDEX_NONE){//MakeCompactPoseIndex 是根据骨骼的索引,找到骨骼索引在索引数组的位置,也就是OutPut.Pose中对应骨骼变化的变换数组的位置。FCompactPoseBoneIndex CPIndex = Output.Pose.GetBoneContainer().MakeCompactPoseIndex(FMeshPoseBoneIndex(MeshIndex));if (CPIndex != INDEX_NONE){FTransform boneTransfrom(FRotator(0.0f, 0.0f, 90.0f));Output.Pose[CPIndex] = boneTransfrom;}}//注意这时候当output.IsNormalized()返回false, Output.ContainsNaN() 返回true,这时候表示没有正确设置。尤其是当该节点与使用AnimNode_SaveCachePose一起使用,output传进来时,所有骨骼都没有设置正确的变换,这时候可以使用Output.ResetToRefPose(),将所有骨骼变换设置为参考姿势。}
在这些基本函数的基础上,您需要提供两个函数的实现,以确保您的节点可以正常同图表的其他部分协同工作:
virtual void CacheBones_AnyThread(const FAnimationCacheBonesContext& Context) {}
virtual void GatherDebugData(FNodeDebugData& DebugData){}
CacheBones_AnyThread用于刷新该节点所引用的骨骼索引,GatherDebugData用于使用"ShowDebug Animation"数据进行调试。为了保持到子项的连接,使用这些是很重要的。
FPoseLink 应该调用它下面的所有节点,以确保您的节点连接的任何姿势连接都会被调用。知道FPoseLink如何工作非常重要,因为任何时候当您调用任何动画函数时,您也必须调用该Pose函数。比如在您的Update_AnyThread函数中您应该调用BasePose->Update。同样,如果您有BasePose作为成员变量,您也应该在CacheBones_AnyThread函数中调用BasePose->CacheBones。(调用FPoseLink的对应函数,FPoseLink会找到它所连接的上一个节点,然后执行上一个节点的对应函数,节点对应函数调用的次序有点类似于递归,从最终动画姿势开始,一直到最开始,见下图)
请参照该示例:
void FAnimNode_BlendListBase::CacheBones_AnyThread(const FAnimationCacheBonesContext& Context)
{
for(int32 ChildIndex=0; ChildIndex<BlendPose.Num(); ChildIndex++)
{
BlendPose[ChildIndex].CacheBones(Context);
}
}
void FAnimNode_BlendListBase::Evaluate_AnyThread(FPoseContext& Output)
{
。。。
for (int32 i = 0; i < PosesToEvaluate.Num(); ++i)
{
int32 PoseIndex = PosesToEvaluate[i];
FPoseContext EvaluateContext(Output);
FPoseLink& CurrentPose = BlendPose[PoseIndex];
CurrentPose.Evaluate(EvaluateContext);
FilteredPoses[i].MoveBonesFrom(EvaluateContext.Pose);
FilteredCurve[i].MoveFrom(EvaluateContext.Curve);
}
。。。
}
参见:https://www.unrealengine.com/zh-CN/blog/creating-custom-animation-nodes
UE4 创建自定义动画节点相关推荐
- 信创办公–基于WPS的PPT最佳实践系列 (创建自定义动画)
信创办公–基于WPS的PPT最佳实践系列 (创建自定义动画) 目录 应用背景 操作步骤 1.动画效果创建 应用背景 动画效果能使幻灯片更加吸引人们,比单纯的文字和图片PPT更有趣味性,那该如何设置动画 ...
- UE4 创建自定义 Slate UI 控件
UE4 创建自定义 Slate UI 控件 文章目录 UE4 创建自定义 Slate UI 控件 前言 一.什么是 Slate 二.创建自己的 Slate 控件 1.模块引用 2.定义 Slate 控 ...
- 用maya的api创建自定义的节点Creating Custom Locator
原文地址 http://www.fevrierdorian.com/blog/post/2010/02/12/Creating-custom-locator-with-Maya-s-Python-AP ...
- 自定义动画属性java_创建酷炫动画效果的10个JavaScript库
原标题:创建酷炫动画效果的10个JavaScript库 1) Dynamics.jsDynamics.js是设计基于物理规律的动画的重要Java库.它可以赋予生命给所有包含CSS 和SVG属性的DOM ...
- Android官方开发文档Training系列课程中文版:动画视图之创建自定义转场动画
原文地址:http://android.xsoftlab.net/training/transitions/custom-transitions.html 自定义转场可以创建自定义动画.比如,可以定义 ...
- 13、Kanzi插件——通过Kanzi Engine插件创建自定义节点+代码解析
一.通过插件创建自定义类型的节点 在类Plugindemo 中添加一行 static kanzi::PropertyTypeEditorInfoSharedPtr makeEditorInfo(); ...
- UE4 创建暂停和结束游戏UI
效果: 步骤: 1.创建控件蓝图,命名为Pause 2.双击打开Pause,拖入一个边界控件并调整大小 3.更改下边界的颜色和透明度 4.将锚点居中,这样屏幕改变时,边界控件会向中间移动和缩放 5.将 ...
- Mr.J-- jQuery学习笔记(十八)--自定义动画
animate(params,[speed],[easing],[fn]) 概述 用于创建自定义动画的函数. 这个函数的关键在于指定动画形式及结果样式属性对象.这个对象中每个属性都表示一个可以变化的样 ...
- JQuery中的animate自定义动画
animate()方法用于创建自定义动画. 概述 .animate( properties [, duration ] [, easing ] [, complete ] ) propert ...
最新文章
- 40年产权的商业地产,个人投资者决不能碰
- 将数组按指定大小分组
- 电脑复制粘贴_手机扫一扫,现实物体隔空复制粘贴进电脑!北大校友的AI新研究,现在变成AR酷炫应用...
- 思达报表工具Style Report基础教程—创建一个多数据块的联合(Union)、镜像(Mirror)...
- python计数器Count
- FDDB数据集(人脸检测)
- 武汉互联网公司和生活成本
- 快手提前批--Java开发面经
- “金三银四“,敢不敢“试”?
- 关于VLOOUP函数与index match函数
- 天才啊!仅用四个整数编写一个贪吃蛇游戏!
- 【Linux】Linux命令详解
- 数据可视化(python代码实现)
- 抖音seo源码,抖音seo矩阵系统源码搭建技术+二开开源代码
- 【历史上的今天】11 月 16 日:RISC-V 领导者出生;微软发布 Windows CE;电子管问世
- Hold不住的老师 HNUST 1588
- 个人前端一些常用的网站
- 动态磁盘和基本磁盘转换
- LVS负载均衡与DR模式
- java系统自启动类和在线计数器
热门文章
- babylonjs创建坐标轴
- thinkpad重装系统不引导_联想电脑为什么重装win7系统后引导不了
- 【渝粤题库】国家开放大学2021春1040公司概论题目
- 【文献阅读笔记】KAM Theory Meets Statistical Learning Theory: Hamiltonian Neural Networks with Non-Zero Trai
- java腾讯滤镜接口_文档中心
- Mac安装与配置jmeterjmeter的使用jmeter生成性能测试报告
- Python随机生成一注双色球彩票
- IBM X3850 m2的一次win2003系统艰难的安装
- 【matlab应用】:生成老电影海报
- 【网络】为什么巨型帧会影响延迟?|网络的带宽,吞吐量,时延的理解|MTU