Unity - Root Motion - how it works - Root Motion 是如何工作的

Root Motion - how it works

Body Transform

The Body Transform is the mass center of the character. It is used in Mecanim’s retargeting engine and provides the most stable displacement model. The Body Orientation is an average of the lower and upper body orientation relative to the Avatar T-Pose.

Body Transform(Body变换对象)是角色的质心。它用于Mecanim的重定目标引擎并提供了最稳定的移动模型。Body Orientation(Body朝向)是相对于Avatar T-Pose的上、下半身方向的平均值。

The Body Transform and Orientation are stored in the Animation Clip(using the Muscle definitions set up in the Avatar). They are the only world-space curves stored in the Animation Clip. Everything else: muscle curves and IK goals (Hands and Feet) are stored relative to the body transform.

Body Transform(Body变换对象)和Body Orientation(Body朝向)存储在动画剪辑中(用于Avatar的Muscle definitions的设置中)。它们是动画剪辑中存储的唯一世界空间下的曲线数据。其他一切:Muscle curves(肌肉曲线)和IK目标(手和脚)是相对于Body Transform(身体变换)存储的。

Root Transform

The Root Transform is a projection on the Y plane of the Body Transform and is computed at runtime. At every frame, a change in the Root Transform is computed. This change in transform is then applied to the Game Object to make it move.

Root Transform(Root变换对象)是 Body的Y平面上的投影**(这里头一定要注意,因为文档写得拗口得要死要死的,什么叫Y平面上,就平面发现与Y轴相同的平面的分量移动,那就时XZ轴的位移),并在运行时计算。在每一帧,都会计算出Root Transform**(Root变换对象)的变化。然后将变换中的更改应用于游戏对象以使其移动。

The circle below the character represents the root transform

Animation Clip Inspector

The Animation Clip Editor settings - Root Transform Rotation, Root Transform Position (Y) and Root Transform Position (XZ) - let you control the Root Transform projection from the Body Transform. Depending on these settings some parts of the Body Transform may be transferred to Root Transform. For example you can decide if you want the motion Y position to be part of the Root Motion (trajectory) or part of the pose (body transform), which is known as Baked into Pose.

动画剪辑编辑器设置—Root Transform RotationRoot Transform Position(Y)Root Transform Position(XZ)—允许您从Body Transform(Body变换对象)控制Root Transform(Root变换对象)投影。根据这些设置,Body Transform(Body变换对象)的某些部分可能会传输到Root Transform(Root变换对象)。例如,您可以决定Y位置的运动是应用于Root Motion(带轨迹的运动)还是应用于Body Transform(Body变换对象),称为Baked into Pose。(应用于Body Transform的就是Baked into Pose,烘焙进动作里头,不影响外部的Root运动的意思,文档说明的乱七八糟)

在这里插入图片描述

Root Transform Rotation

Bake into Pose: The orientation will stay on the body transform (or Pose). The Root Orientation will be constant and delta Orientation will be identity. This means that the Game Object will not be rotated at all by that AnimationClip.

Bake into Pose(烘焙到动作):方向将保持在Body Transform中(或叫:在动作中)。Root Orientation不变,delta Orientation(变换的差距方向,意思就是不会有Orientation的变化,但这里说的很拗口)将保持一致为identity值。这意味着该AnimationClip(动画剪辑)根本不会旋转Game Object游戏对象。

Only AnimationClips that have similar start and stop Root Orientation should use this option. You will have a Green Light in the UI telling you that an AnimationClip is a good candidate. A suitable candidate would be a straight walk or a run.

仅当具有“开始”和“停止”的动画剪辑的Root Orientation是类似的动画剪辑才应使用此选项。用户界面中会有一个绿灯,告诉您动画剪辑是适合的。一个适合动画,如:行走或跑动。

Based Upon: This lets you set the orientation of the clip. Using Body Orientation, the clip will be oriented to follow the forward vector of body. This default setting works well for most Motion Capture (Mocap) data like walks, runs, and jumps, but it will fail with motion like strafing where the motion is perpendicular to the body’s forward vector. In those cases you can manually adjust the orientation using the Offset setting. Finally you have Original that will automatically add the authored offset found in the imported clip. It is usually used with Keyframed data to respect orientation that was set by the artist.

Based Upon(基于):这可以让你设置剪辑的方向。使用Body Orientation(Body朝向),剪辑将朝向跟随body transform.foward向量的方向。这个默认设置对大多运动捕捉(Mocap:实时动捕设备数据的产品)数据(如行走、跑步和跳跃)都很有效,但是如果是对于垂直于body transform.forward向量的动作,它将失败,如:垂直于身体部分动作的横扫动作。在这些情况下,可以手动调整Offset朝向偏移设置。最后,你将得到在模型动画剪辑导入自动添加好校验过的Offset的Original(原始偏移值,大概就时动画文件中的Offset值吧,我只能理解到这,真不知道是什么确切的意思)。它通常与关键帧数据一起使用尽量达到朝向美术同学编辑好的方向。

Offset: used to enter the offset when that option is chosen for Based Upon.

Offset:该值,将再Based Upone选项选中时使用。

Root Transform Position (Y)

This uses the same concepts described in Root Transform Rotation.

这与Root Transform Rotation 中描述的概念相同。

Bake Into Pose: The Y component of the motion will stay on the Body Transform (Pose). The Y component of the Root Transform will be constant and Delta Root Position Y will be 0. This means that this clip won’t change the Game Object Height. Again you have a Green Light telling you that a clip is a good candidate for baking Y motion into pose.

Bake Into Pose(烘焙到动作):动作的Y分量将保持在Body Transform中(或叫:在动作中)。Root Transform的Y分量将不变,Delta Root Position Y(变换的根对象的Y分量变换差值,但这里说的很拗口)保持为0。这意味着该AnimationClip(动画剪辑)不会旋转Game Object游戏对象的高度。同样,如果动作Y分量烘焙到Body Transform中适合的话,界面上回有个绿灯显示。

Most of the AnimationClips will enable this setting. Only clips that will change the GameObject height should have this turned off, like jump up or down.

大多数动画剪辑将启用此设置。只有那些会改变游戏对象高度的剪辑才应该关闭它,比如上下跳跃。

Note: the Animator.gravityWeight is driven by Bake Into Pose position Y. When enabled, gravityWeight = 1, when disabled = 0. gravityWeight is blended for clips when transitioning between states.

注意:Animator.gravityWeight 由Bake Into Pose Y值驱动。启用时,gravityWeight=1,禁用时=0。在状态之间转换时,gravityWeight。将会以状态之间做混合值处理

Based Upon: In a similar way to Root Transform Rotation you can choose from Original or Mass Center (Body). There is also a Feet option that is very convenient for AnimationClips that change height (Bake Into Pose disabled). When using Feet the Root Transform Position Y will match the lowest foot Y for all frames. Thus the blending point always remains around the feet which prevents floating problem when blending or transitioning.

Based Upon:以类似Root Transform Rotation的方式,可以从Original或Mass Center(基于Body的质心)中选择。还有一个Feet(脚)选项,对于更改高度的动画剪辑非常方便(Bake Into Pose需关闭)。使用Feet(脚)时,Root Transform Position的Y将与所有帧的脚部位最小Y的匹配。因此,混合点始终保持在脚的周围,以防止混合或转换时出现浮空问题。

Offset: In a similar way to Root Transform Rotation, you can manually adjust the AnimationClip height using the Offset setting.

Offset:与Root Transform Rotation类似,可以使用Offset设置来手动调整动画剪辑的高度。

Root Transform Position (XZ)

Again, this uses same concepts described in Root Transform Rotation and Root Motion Position (Y).

同样,这也使用了Root Transform RotationRoot Motion Position (Y) 中描述的相同概念。

Bake Into Pose will usually be used for “Idles” where you want to force the delta Position (XZ) to be 0. It will stop the accumulation of small deltas drifting after many evaluations. It can also be used for a Keyframed clip with Based Upon Original to force an authored position that was set by the artist.

Root Transform Position (XZ) 的 Bake Into Pose 通常用于变量Position (XZ) 为0的“Idles”(空闲、待机)动画。将可以阻止多次很小量的的 xz 积累而成的飘动问题。它还可以用于基于Based Upon Original的关键帧剪辑,以强制符合由美术同学设置的的xz位置。

Loop Pose

Loop Pose (like Pose Blending in Blend Trees or Transitions) happens in the referential of Root Transform. Once the Root Transform is computed, the Pose becomes relative to it. The relative Pose difference between Start and Stop frame is computed and distributed over the range of the clip from 0–100%.

Loop Pose(循环动作)(就像混合树或过渡中的动作混合)以Root Transform 为参照。一旦Root Transform被计算出来,动作就变成相对于它的了。计算开始帧和停止帧之间的相对动作差,并将其分布在剪辑的0–100%范围内。(即,开启了Loop Pose循环动作的话,unity 会将开始帧与结束帧之间的动作差异都自动混合过渡在整个剪辑动画中)

Generic Root Motion and Loop Pose

This works in essentially the same as Humanoid Root Motion, but instead of using the Body Transform to compute/project a Root Transform, the transform set in Root Node is used. The Pose (all the bones which transform below the Root Motion bone) is made relative to the Root Transform.

Generic Root Motion and Loop Pose(一般模型的,即非人形动画的Root Motion和Loop Pose),这与人形Root Motion的工作原理基本相同,但使用Root Node(根节点)中的transform(变换)集,而不是使用Body Transform来计算/投影Root Transform。动作(在Root Motion骨骼下的所有骨骼的transform)相对于Root Transform进行。


Tutorial: Scripting Root Motion for “in-place” humanoid animations

教程:人形动画中使用脚本来驱动Root Motion

Sometimes your animation comes as “in-place”, which means if you put it in a scene, it will not move the character that it’s on. In other words, the animation does not contain “root motion”. For this, we can modify root motion from script. To put everything together follow the steps below (note there are many variations of achieving the same result, this is just one recipe).

有时候你的动画是以“原地”的形式出现的,这意味着如果你把它放在一个场景中,它不会移动它所在的角色。换句话说,动画不包含“root motion(根运动)”。为此,我们可以从脚本修改root motion。要将所有内容组合在一起,请遵循以下步骤(请注意,实现相同结果有很多种方法,这只是其一的方法)。

  • Open the inspector for the FBX file that contains the in-place animation, and go to the Animation tab

  • Make sure the Muscle Definition is set to the Avatar you intend to control (let’s say this avatar is called Dude, and it has already been added to the Hierarchy View).

  • Select the animation clip from the available clips

  • Make sure Loop Pose is properly aligned (the light next to it is green), and that the checkbox for Loop Pose is clicked

  • 在包含原地动画的FBX文件的Inspector窗口中,选中"Animation"tab项

  • 确定好你想要控制的Avatar的Muscle Definition被设置好(假设Avatar叫:Dude,并且已将他添加到Hierarchy 视图中了)

  • 选中可用的clips中的动画剪辑

  • 确保Loop Pose(循环动作)是适合的(旁边的绿灯提示),且确保Loop Pose的选项点击选中状态

(以上第二点的Muscle Definition在新版中是不需要设置的,一般Avatar选择Create from this model,该Avatar的Muscle&Setting都有默认的值,我也不知道那个旧的版本是上面那样的)

在这里插入图片描述

  • Preview the animation in the animation viewer to make sure the beginning and the end of the animation align smoothly, and that the character is moving “in-place”

  • On the animation clip create a curve that will control the speed of the character (you can add a curve from the Animation Import inspector Curves-> +)

  • Name that curve something meaningful, like “Runspeed”

  • 在animation viewer预览动画,以确保动画的开始和结束的平滑衔接,还有角色是原定的

  • 在动画剪辑创建Curve曲线来控制角色的速度(在Animation Import Inspector中的Curves点"+"号)

  • 给曲线命和有意义的名字,如:“Runspeed”

在这里插入图片描述

  • Create a new Animator Controller, (let’s call it RootMotionController)

  • Drop the desired animation clip into it, this should create a state with the name of the animation (say Run)

  • Add a parameter to the Controller with the same name as the curve (in this case, “Runspeed”)

  • 创建一个新的Animator Controller(资源命名为RootMotionController

  • 拖入想要的动画剪辑进去Animator的状态编辑区中,它将自动创建名称为动画剪辑相同的状态(如:名称为Run的动画剪辑,自动创建出来的状态的名称就为:Run

  • 给Animator添加参数,在Parameters中添加名称和Curve曲线中一样的float参数(在这个栗子中,我们名为:“Runspeed”)

在这里插入图片描述

  • Select the character Dude in the Hierarchy, whose inspector should already have an Animator component.

  • Drag RootMotionController onto the Controller property of the Animator

  • If you press play now, you should see the “Dude” running in place

  • 在"Hierarchy"视图中选中Dude角色对象,该对象应该自动添加好了Animator component组件的。

  • 拖拽RootMotionController到Animator的Controller属性中

  • 如果你现在就运行播放,你将看到"Dude"处于原地跑动

Finally, to control the motion, we will need to create a script (RootMotionScript.cs), that implements the OnAnimatorMove callback:-

最后,要控制有动画表现,我们将要创建一个名为RootMotionScript.cs的脚本,并且实现好OnAnimatorMove 回调

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Animator))]
    
public class RootMotionScript : MonoBehaviour {
            
    void OnAnimatorMove()
    {
            Animator animator = GetComponent<Animator>(); 
                              
            if (animator)
            {
     Vector3 newPosition = transform.position;
               newPosition.z += animator.GetFloat("Runspeed") * Time.deltaTime; 
     transform.position = newPosition;
            }
    }
}

You should attach RootMotionScript.cs to the “Dude” object. When you do this, the Animator component will detect that the script has an OnAnimatorMove function and show the Apply Root Motion property as Handled by Script

将RootMotionScript.cs附加到“Dude”对象后,Animator component(Animator组件)将会自动检测脚本中有没实现OnAnimatorMove函数,如果有实现,那么Apple Root Motion属性将显示:Handled by Script

在这里插入图片描述


自己测试

使用脚本读取Animator.deltaPosition来位移

    private void OnAnimatorMove()
    {
        var p = transform.position;
        p += animator.deltaPosition;
        transform.position = p;
    }

总结

(总之我发现,大部分国外的技术文档,都写得很烂,不是一般的烂,很多语句不通,在翻译过程中,我只能魔改一下意思,直译的话,简直无法直视)

使用Root Motion来功能来控制模型移动时,时很自然的位移动画变现,他可以完美的呈现出美术同学想要的位移想过,但同时肯定对开发成本的增加


Pose、Trajectory与Body、Root

这里我们要了解:Pose,与Trajectory两种动画

  • Body Transform (pose:姿势)
  • Root Transform (trajectory:轨迹)

Bake Into Pose (烘焙为姿势)

Bake Into Pose:也就是将变换设置为Body Transform(pose)的一部分。

如果把变换设置成Body Transform(pose)的一部分,就相当这些变换是属于动画本身的一部分,即无论是否设置Apply Root Motion,在场景中,我们都会看到模型位置或角度的变化。因为Body Transform不影响模型(GameObject)实际的位置和角度,所以这里只是纯粹的动画效果,模型(GameObject)的位置和角度参数值不变

如果设置成Root Transform,Root Transform将影响模型(GameObject)的实际位置和角度(前提是要设置“Apply Root Motion”,如果不设置Apply Root Motion的话,也就是说变换将不应用,场景中的模型(GameObject)位置或角度是不会有变化的<Transform值自然也不变>,就像一个行走动画,可能一直在原地行走)。

Apply Root Motion

Apply Root Motion作用如下:

  • 决定是否应用Root Transform:

    如果勾选【Apply Root Motion】,则应用Root Transform在播放动画的同时,模型(GameObject)的位置和角度会同时跟着变化。如果不勾选【Apply Root Motion】,则不应用Root Transform,所有的Root Transform都将不起任何作用。即相当于所有没有Bake into Pose 的变换都不起作用了。

  • 在动画结束后,将Body Transform中的变化应用到模型:

    这里是结束的时候才应用,也就是说动画的时候,模型的(GameObject)position、rorate等参数是不变的,当动画结束之后,开始新的动画之前才会改变,注意这里跟前面提到的Root Transform的区别

参考:根运动 Root Motion – 工作原理


References

猜你喜欢

转载自blog.csdn.net/linjf520/article/details/90718817