Unity3D的Legacy动画系统中应用Root Motion

本文介绍了一个Unity脚本,用于在游戏中应用角色的Root Motion。通过跟踪角色骨骼的根节点位移并将其应用于游戏对象的位置变化,可以实现更真实的动画效果。此外,还提供了循环动画的处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.youkuaiyun.com/neil3d/article/details/41724705

在动画时间内计算每帧动画的位移,即父节点的localPosition

把此位移给transform.position

最后处理一下循环动画,即用AnimationState.normalizedTime来控制

using UnityEngine;
using System.Collections;

public class ApplyRootMotion : MonoBehaviour 
{
	public Transform m_flagObject;	// 用来测试位置的一个对象

	//-- Root Motion 控制变量
	Transform m_rootBone;
    Vector3 m_lastRootPos;
    Vector3 m_rootMotion;
    int m_lastAnimTime;

	void Start () 
	{
		//-- 从SkinnedMeshRenderer中读取Root Bone
		SkinnedMeshRenderer skinMesh = this.gameObject.GetComponentInChildren<SkinnedMeshRenderer>();
        m_rootBone = skinMesh.rootBone;
        print(m_rootBone.name);

        //-- 变量初始化
        m_rootMotion = Vector3.zero;
        m_lastRootPos = m_rootBone.localPosition;
        m_lastAnimTime = 0;
	}
	
	void Update () 
	{
		//-- Apply Root Motion
		Vector3 nextPos = this.transform.position + m_rootMotion;
        this.transform.position = nextPos;

        //-- 测试代码:更新测试物体的位置
        Vector3 flagPos = m_flagObject.position;
        flagPos.x = nextPos.x;
        flagPos.z = nextPos.z;
        m_flagObject.position = flagPos;

        //-- 测试代码:更新摄像机
        Camera.main.transform.LookAt(this.transform);
	}

	void LateUpdate()
    {
		AnimationState animState = this.animation["walking"];

		if ((int)animState.normalizedTime > m_lastAnimTime)
		{
        	//-- 动画循环处理
        	m_lastRootPos = m_rootBone.localPosition;
        	m_rootMotion = Vector3.zero;
        }
        else
        {
        	//-- 计算当前帧的Root Motion
        	Vector3 rootPos = m_rootBone.localPosition;
        	m_rootMotion = rootPos - m_lastRootPos;
        	m_lastRootPos = rootPos;
        	rootPos.x = 0;
        	rootPos.z = 0;
        	m_rootMotion.y = 0;
        	m_rootBone.localPosition = rootPos;
        }
        m_lastAnimTime = (int)animState.normalizedTime;
        //m_lastAnimTime = 0;
    }
}


<think>好的,现在我需要帮助用户解决关于Unity中导入动画时缺少“Root Transform Rotation”或“Root Transform Position”设置的问题。用户之前已经询问过如何处理“Root contains root motion curves”的问题,现在他们可能遇到了另一个相关的问题,即导入的动画在Unity的动画导入设置中缺少这些根变换选项。我需要详细思考如何回答这个问题。 首先,我需要回忆Unity中动画导入的设置。当导入FBX动画时,在Inspector窗口的Animations标签下,通常会有Root Transform Rotation、Position (Y)和Position (XZ)的设置,这些用于控制根运动的应用方式。如果用户发现这些选项缺失,可能的原因是什么? 可能的原因有几个:首先,动画类型可能被错误地设置为Legacy而不是Humanoid或Generic。Legacy动画系统可能不显示这些选项。其次,如果模型是Humanoid类型,Unity会自动处理根骨骼,可能隐藏这些设置,或者用户可能没有正确配置Avatar。此外,文件结构问题,比如没有正确识别根骨骼,也可能导致这些选项不显示。 接下来,我需要验证这些可能的原因。例如,如果用户将动画类型设置为Humanoid,并且正确配置了Avatar,那么Root Transform的设置应该会出现。如果设置为Generic,可能需要指定根节点才能看到这些选项。而如果设置为Legacy,这些选项确实不会出现。 然后,我需要考虑解决方案。首先,检查动画类型是否为Humanoid或Generic,如果是Legacy,需要更改为正确的类型。其次,如果是Humanoid类型,可能需要重新配置Avatar,确保根骨骼被正确识别。如果是Generic类型,可能需要手动指定根骨骼节点,这样Root Transform的设置才会出现。此外,用户可能需要检查FBX文件的结构,确保根骨骼存在并且命名正确,例如Hips或Root。 另外,如果用户希望手动处理根运动,他们可能需要使用脚本来控制角色的移动,而不是依赖Unity的自动根运动设置。这需要编写代码来提取动画中的位移数据,并应用到角色控制器上。 在思考过程中,还需要考虑用户可能的操作步骤是否正确,例如是否在导入设置中正确选择了动画片段,或者在Rig标签下是否正确配置了动画类型。可能用户忽略了一些步骤,导致选项没有显示出来。 此外,需要注意不同Unity版本之间的差异,某些版本的Unity可能在界面或选项名称上有所不同,需要确保提供的解决方案适用于大多数版本,或者指出版本差异。 最后,总结可能的解决方案,分步骤说明,并给出示例或注意事项,帮助用户逐步排查问题,确保他们能够找到缺失的Root Transform设置的原因,并进行正确的配置。</think>在 Unity 中导入动画时,如果发现 **Animations** 标签下缺少 `Root Transform Rotation` 或 `Root Transform Position (Y/XZ)` 等设置(如下图所示),通常是由于动画的 **导入配置** 或 **骨骼结构** 存在问题。以下是详细的解决方案: --- ### **1. 确认动画导入类型** Unity 的根运动(Root Motion)设置仅在 **Humanoid** 或 **Generic** 动画类型中可见。如果类型设置为 **Legacy**,这些选项会直接隐藏。 #### **步骤一:检查动画类型** 1. 选中动画文件(如 `.fbx`),在 Inspector 窗口中切换到 **Rig** 标签。 2. 确认 **Animation Type** 设置为: - **Humanoid**(人形角色):Unity 会自动处理根骨骼。 - **Generic**(通用类型):需手动指定根骨骼节点。 - 如果设为 **Legacy**,需更改为上述类型之一。 #### **步骤二:重新配置 Humanoid/Generic 类型** - **Humanoid 类型**: 1. 确保模型骨骼符合人形结构(如包含 Hips、Spine 等节点)。 2. 点击 **Configure Avatar** 生成 Avatar,并确认骨骼映射正确。 3. 返回 **Rig** 标签,选择 **Humanoid** 并应用。 - **Generic 类型**: 1. 在 **Rig** 标签下选择 **Generic**。 2. 在 **Root Motion Node** 中手动指定根骨骼(如 "Hips" 或 "Root")。 3. 保存后切换至 **Animations** 标签,根运动相关选项会显示。 --- ### **2. 检查骨骼结构** 如果动画文件中没有明确的根骨骼节点,Unity 可能无法识别根运动参数。 #### **步骤一:在 3D 软件中修复** 1. 在 Blender/Maya/3ds Max 中打开模型文件。 2. 确保存在一个明确的根骨骼(通常命名为 "Hips" 或 "Root"),且位移/旋转曲线绑定在此骨骼上。 3. 删除其他多余的根骨骼,确保层级结构清晰。 4. 重新导出为 FBX 并导入 Unity。 #### **步骤二:在 Unity 中指定根节点** 1. 在 **Rig** 标签下(Generic 类型): - 手动填写 **Root Motion Node** 为根骨骼名称(如 "Hips")。 2. 如果根骨骼未识别,尝试在 **Avatar Definition** 中选择 **Create From This Model**。 --- ### **3. 手动处理根运动(无 Root Transform 选项)** 如果上述方法无效,或需要完全手动控制根运动,可通过脚本实现: #### **步骤一:禁用 Unity 的自动根运动** 1. 在 Animator 组件中取消勾选 **Apply Root Motion**。 2. 在动画文件的 **Animations** 标签下,确保所有 `Bake Into Pose` 选项已勾选。 #### **步骤二:通过脚本提取动画位移** ```csharp using UnityEngine; public class ManualRootMotion : MonoBehaviour { private Animator animator; private Vector3 deltaPosition; private Quaternion deltaRotation; void Start() { animator = GetComponent<Animator>(); } void OnAnimatorMove() { // 获取动画的位移和旋转增量 deltaPosition = animator.deltaPosition; deltaRotation = animator.deltaRotation; // 手动应用到角色(例如通过 CharacterController) transform.Translate(deltaPosition); transform.rotation *= deltaRotation; } } ``` --- ### **4. 常见问题排查** - **问题**:动画片段未正确分割。 **解决**:在 **Animations** 标签下,确认已创建动画片段(Clip),并检查其设置。 - **问题**:FBX 文件未包含骨骼信息。 **解决**:重新导出 FBX 时勾选 **Embed Media** 和 **Animation** 选项。 - **问题**:Unity 版本兼容性。 **解决**:尝试在 2019.4 LTS 或更新版本中导入。 --- ### **总结** | 情况 | 解决方案 | |------|----------| | 动画类型错误 | 改为 **Humanoid/Generic** 类型,配置 Avatar 或根节点。 | | 骨骼结构问题 | 在 3D 软件中修复骨骼层级,确保存在根节点。 | | 完全手动控制 | 禁用 `Apply Root Motion`,通过脚本提取 `animator.deltaPosition`。 | 通过以上方法,即使动画文件本身未包含 Root Transform 设置,也可以通过 Unity 的配置或脚本实现根运动的控制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值