Unity RootMotion简单尝试记录
找了一大圈资料,基本都是各种copy,讲的基本都是unity怎么使用~为此,我还特意去看了ue的源码,想着对比看看!这里本来是想要说明工作的整个过程的,但是因为结果不理想,我也不敢说这是在说原理。
本文只是在对unity root motion的一个简单的尝试记录!
Root Motion 工作原理
官方文档的说明
https://docs.unity3d.com/cn/current/Manual/RootMotion.html
下面就是一套瞎操作!
资源导入及简单设置
模型导入的时候使用的是Humanoid
动画导入也要选择Humanoid
Animation页签
在Root Motion Node中使用的是< None >的时候,界面就和网上google或者官方的界面样式一致了!
like this! https://docs.unity3d.com/cn/current/Manual/RootMotion.html
Apply Root Motion 在Root Motion Node为none的测试
直接运动到帧末的时候,GameObject在Z轴的位置是 -3.99 !
展开一下动作资源,在使用Root Motion Node为none时只有Root T和Root Q,这两个curve的最后数值!(获取的代码在文后)
居然有差异!!!
排查差异
把关于Aniomation的优化全关掉!
运行得到的结果没有变化!!
这个看情况的,如果本来和动作同学设定的值变成较大,关掉这些优化后,还是有变化的。咨询了一下动作的同学,得到设置的值
这一下子就懵逼了我。
https://forum.unity.com/threads/mecanim-root-motion-for-generic-rig-quadruped.169891/ https://forum.unity.com/threads/is-there-a-way-to-extract-rootmotion-curves-from-a-clip.610579/ https://forum.unity.com/threads/make-root-motion-in-animation-clip.250723/
问题是我在Animation中没有看到Motion!!!
Apply Root Motion 在Root Motion Node为Root的测试
尝试将Root Motion Node为Root
然后再Animation中就能找到Motion Curve
尝试获取一下Root T和Root Q(或者Motion T和Motion Q)的Curve,然后读取一下数据,也测试一下Apply Root Motion的执行结果!
Apply Root Motion的执行结果:
Curve读取的结果:
展开Curve看看
基本就是-3.7呀!!怎么Unity的Apply Root Motion成了-4呢?而且3dmax中设置也是-4!!!(Apply Root Motion的结果更加逼近3dmax)
自己在Unity中搞一个Animaion试试
赞,我设置的10呀!!
去掉Apply Root Motion
这就一样了!!!
晕了,等其他大佬分享吧!现在资料有点少~或者以后看UE的源码再分析一下。
代码:
if (Clip.hasMotionCurves)
{
var bindings = AnimationUtility.GetCurveBindings(Clip);
// 也可以改成Root测试!
var pName = &#34;Motion&#34;;
foreach (var bind in bindings)
{
if (bind.propertyName == $&#34;{pName}T.x&#34;)
{
curve_x = AnimationUtility.GetEditorCurve(Clip, bind);
x = curve_x.Evaluate(7);
}
if (bind.propertyName==$&#34;{pName}T.y&#34;)
{
curve_y = AnimationUtility.GetEditorCurve(Clip, bind);
y = curve_y.Evaluate(7f);
}
if (bind.propertyName==$&#34;{pName}T.z&#34;)
{
curve_z = AnimationUtility.GetEditorCurve(Clip, bind);
z = curve_z.Evaluate(7f);
}
if (bind.propertyName==$&#34;{pName}Q.x&#34;)
{
curve_Qx = AnimationUtility.GetEditorCurve(Clip, bind);
qx = curve_Qx.Evaluate(7f);
}
if (bind.propertyName==$&#34;{pName}Q.y&#34;)
{
curve_Qy = AnimationUtility.GetEditorCurve(Clip, bind);
qy = curve_Qy.Evaluate(7f);
}
if (bind.propertyName==$&#34;{pName}Q.z&#34;)
{
curve_Qz = AnimationUtility.GetEditorCurve(Clip, bind);
qz = curve_Qz.Evaluate(7f);
}
if (bind.propertyName==$&#34;{pName}Q.w&#34;)
{
curve_Qw = AnimationUtility.GetEditorCurve(Clip, bind);
qw = curve_Qw.Evaluate(7f);
}
}
} 动画输出不准的问题之前也有注意到过,比如导进max里面正常,导进Unity那边就Shake(即使关了压缩+不Loop),或者一些小幅度运动有明显差异,尤其是ApplyRootMotion这种每一帧算差量apply一次的状况,还有就是长父子链矩阵要乘很多次的状况
个人理解是Unity实时运行的采样输出+滤波,和DCC那边是有差异的,再加上计算机浮点不精确,最后输出就是会有点不准,但对于RootMotion而言基本已经够用了,能保证人物不滑步,动画有基本正确的表现就好
消除Shake,可以优化父子结构(所有节点优化为Root的一阶子物体,靠Max那边绑定追踪到原本骨架的节点运动),取消压缩,不Loop/LoopPose,或者DCC确保初末Pose一致
如果有过分精确的动作要求,应该是由Unity这边用计算动画,或者参数化的一些方式来做 我是要做帧同步用,所以才想看看怎么提取数据[捂脸] 引擎专家,厉害。[赞] [捂脸]title而已,就是学习一下
页:
[1]