[UE4][Custom Animation Graph Node]Evaluate Pose by Curve
目的:根据曲线值获得当前动作帧。用于实现各种通过曲线同步的功能。
方法:继承FAnimNode_Base创建自定义动画节点。重写Evaluate部分。创建相应的AnimGraphNode。可参考前一篇http://blog.csdn.net/u010831746/article/details/50733287
Evaluate : 1. 根据曲线Value(Y轴)值获得Time(X轴)值。
曲线KeyArray所在位置。AnimSequenceBase : RawCurveData.
类型AnimCurveTypes.h:FRawCurveTracks
曲线记录是TArray<FRichCurveKey>。每个key中存有Time和Value。根据输入的CurveValue,遍历Array查找Value最接近的Key,返回Time。
2.根据Time值获得动画POS
AnimSequence->GetAnimationPose(…, Time, …)输出Pose。
主要代码:
AnimNode_EvaluatePose.h
/*!
* \file AnimNode_EvaluatePose.h
* \date 2016/03/29 17:45
*
* \author: Jia Zhipeng
* Contact: jiazhipeng@pwrd.com
*
* \brief: 根据曲线获得当前Pose. Get Pose based on curve value.
*
* \note:
*/
#pragma once
#include "Animation/AnimNodeBase.h"
//#include "AnimNode_SkeletalControlBase.h"
#include "AnimNode_EvaluatePose.generated.h" USTRUCT()
struct FAnimNode_EvaluatePose :public FAnimNode_Base
{
GENERATED_USTRUCT_BODY() UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Settings, meta = (PinShownByDefault))
UAnimSequenceBase* Sequence; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Settings, meta = (PinShownByDefault))
FName CurveName; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Settings, meta = (PinShownByDefault))
float CurveValue; UAnimInstance* MyInstance;
public:
// Constructor
FAnimNode_EvaluatePose(); // FAnimNode_Base interface
virtual void Initialize(const FAnimationInitializeContext& Context) override;
virtual void CacheBones(const FAnimationCacheBonesContext& Context) override;
virtual void Evaluate(FPoseContext& Output) override;
virtual void OverrideAsset(UAnimationAsset* NewAsset) override;
virtual void GatherDebugData(FNodeDebugData& DebugData) override;
// End of FAnimNode_Base interface// };
AnimNode_EvaluatePose.cpp
//Iterate Animation's curve's keys to get current time
void FAnimNode_EvaluatePose::Evaluate(FPoseContext& Output)
{
//CurveValue is connected to AnimInstance’s variable in AnimBlueprint, but it is not updated when executing this node. So how to get variable of AnimInstance? 2 ways.
//1. EvaluateGraphExposedInputs.Execute(Output); Cause crash. Explore this method in the future.
//2. Get property from AnimInstance. But in this way, the variable’s name has to be specified. Temporarily use this method.
UFloatProperty* FloatProp = Cast<UFloatProperty>(PW_PropertyTools::FindProperty(MyInstance, TEXT("Horiz Movement Speed")));
if (!FloatProp)
{
UE_LOG(LogTemp, Warning, TEXT("Horiz Movement Speed Not found"));
return;
}
float HorzSpeed = FloatProp->GetPropertyValue_InContainer(MyInstance);
CurveValue = HorzSpeed; USkeleton* Skeleton = Sequence->GetSkeleton();
if (!Skeleton)
{
UE_LOG(LogTemp, Warning, TEXT("FAnimNode_EvaluatePose::Evaluate fail to find skeleton"));
return;
}
FSmartNameMapping* NameMapping = Skeleton->SmartNames.GetContainer(USkeleton::AnimCurveMappingName);
// retrieve curve
USkeleton::AnimCurveUID Uid;
if (!NameMapping->Exists(CurveName))
{
UE_LOG(LogTemp, Warning, TEXT("FAnimNode_EvaluatePose::Evaluate fail to find curve %s"), *CurveName.ToString());
return;
} Uid = *NameMapping->FindUID(CurveName);
FFloatCurve * CurveToCompute = static_cast<FFloatCurve*>(Sequence->RawCurveData.GetCurveData(Uid));
if (!CurveToCompute)
{
UE_LOG(LogTemp, Warning, TEXT("FAnimNode_EvaluatePose::Evaluate fail to find curve %s"), *CurveName.ToString());
return;
} auto FloatCurve = CurveToCompute->FloatCurve;
float OutTime = 0.0f;
BinarySeach(FloatCurve, CurveValue, OutTime);
if ((Sequence != NULL) && (Output.AnimInstance->CurrentSkeleton->IsCompatible(Sequence->GetSkeleton())))
{
Sequence->GetAnimationPose(Output.Pose, Output.Curve, FAnimExtractContext(OutTime, Output.AnimInstance->ShouldExtractRootMotion()));
}
else
{
Output.ResetToRefPose();
}
}
[UE4][Custom Animation Graph Node]Evaluate Pose by Curve的更多相关文章
- UE4 custom depth 自定义深度
用途1: 半透明材质中实现遮挡Mesh自己其他部分的效果. 不遮挡效果如下: 遮挡后效果如下: 实现方法: 深度信息是越远值越大,使用两个Mesh,一个正常渲染,另一个渲染到custom depth ...
- tbb flow graph node types
- 泡泡一分钟: A Linear Least Square Initialization Method for 3D Pose Graph Optimization Problem
张宁 A Linear Least Square Initialization Method for 3D Pose Graph Optimization Problem "链接:https ...
- UE4高级运动系统(Advanced Locomotion System V3)插件分析
Advanced Locomotion System V3是虚幻商城的一款第三方插件.它相比UE4的基础走跑跳表现,实现了更多动作游戏里常用的运动特性,虽然价格定价不菲,依然备受关注.笔者试用了这款插 ...
- Qt5 QtQuick系列----QtQuick的Secne Graph剖析(1)
教是言词, 实不是道,道本无言, 言说是妄.------- 达摩 Qt 5提出了一个新的渲染底层,以替代Qt4时期的Graphics View,这个渲染底层就是Scene Graph.Scene Gr ...
- [LintCode] Find the Weak Connected Component in the Directed Graph
Find the number Weak Connected Component in the directed graph. Each node in the graph contains a ...
- Lintcode: Route Between Two Nodes in Graph
Given a directed graph, design an algorithm to find out whether there is a route between two nodes. ...
- 【LEETCODE OJ】Clone Graph
Problem link: http://oj.leetcode.com/problems/clone-graph/ This problem is very similar to "Cop ...
- lintcode:Find the Connected Component in the Undirected Graph 找出无向图汇总的相连要素
题目: 找出无向图汇总的相连要素 请找出无向图中相连要素的个数. 图中的每个节点包含其邻居的 1 个标签和 1 个列表.(一个无向图的相连节点(或节点)是一个子图,其中任意两个顶点通过路径相连,且不与 ...
随机推荐
- <![CDATA[ ]]> 的作用
在xml文件中 一些特殊字符需要去除其本意,就要用到 <![CDATA[ ]]>,,比如 ibitis的sqlmap.xml 中 要比较大小不能直接用 < 或者 > , ...
- LDAP与SSH
一般情况下,客户端配置好之后,ssh是可以直接用的,若不能,则需手动配置 1:vim /etc/ssh/sshd_config 把UsePAM改成yes 2:在vim /etc/pam.d/sshd添 ...
- iOS启动页设置
点击项目->TARGETS->App Icons and Launch Images->Launch Images Source->Use Asset Catalog...-& ...
- font-family 字体
宋体 SimSun黑体 SimHei微软雅黑 Microsoft YaHei微软正黑体 Microsoft JhengHei新宋体 NSimSun新细明体 PMingLiU细明体 MingLiU标楷体 ...
- java中的static使用--静态变量、静态方法
Java 中的 static 使用之静态变量 大家都知道,我们可以基于一个类创建多个该类的对象,每个对象都拥有自己的成员,互相独立.然而在某些时候,我们更希望该类所有的对象共享同一个成员.此时就是 s ...
- hdu 1251 统计难题 (字典树入门题)
/******************************************************* 题目: 统计难题 (hdu 1251) 链接: http://acm.hdu.edu. ...
- Nginx-->基础-->理论-->001:Nginx基本介绍
一.nginx基本介绍 传统上基于进程或者线程模型架构的web服务通过每进程或者每线程处理并发连接请求,这势必毁在网络和I/O操作时产生阻塞,其另外一个必然结果则是对内存和CPU的利用率低下,产生一个 ...
- CSS自动换行
style="word-break:break-all;word-wrap:break-word;"
- JavaScript基础知识整理(1)
粗略理解,努力入门中 1.在html中引入外部脚本: <script src="filename.js"></script> 2.注释: 多于一行的长注 ...
- JAVA中获得一个月最大天数的方法(备忘)
Calendar 类是一个抽象类,为日历字段之间的转换提供了一些方法.其中有一个重要方法 getActualMaximum ,该方法用于返回指定日历字段实际的最大值. 利用这个方法(Calendar. ...