动画系统 关于动画系统的根运动RootMotion

【原文参考】http://blog.csdn.net/neil3d/article/details/41724705

 

动画将控制RootBone对象的坐标、旋转、比例等,不合适的称为根运动吧

 

此脚本,就是将RootBone对象的坐标、旋转、比例等映射到父对象上,产生根运动的效果,不会出现感觉滑帧的情况出现

 

legacy参考脚本:

using UnityEngine;
using System.Collections;

public class ApplyRootMotion : MonoBehaviour 
{

	//-- Root Motion 控制变量
	public Transform m_rootBone;

    Vector3 m_lastRootPos;
    Vector3 m_rootMotion;

    int m_lastAnimTime;

	Vector3 m_lastRootRot;
	Vector3 m_rootRot;

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

        //-- 变量初始化
		m_rootMotion = Vector3.zero;
        m_lastRootPos = m_rootBone.localPosition;

		m_rootRot = Vector3.zero;
		m_lastRootRot = m_rootBone.localRotation.eulerAngles;

        m_lastAnimTime = 0;
	}
	
	void Update () 
	{
		//-- Apply Root Motion
		Vector3 nextPos = this.transform.position + m_rootMotion;
        this.transform.position = nextPos;

		this.transform.rotation = Quaternion.Euler(this.transform.rotation.eulerAngles + m_rootRot);


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

	}

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

		print((int)animState.normalizedTime +"  : "+m_lastAnimTime);
		if ((int)animState.normalizedTime > m_lastAnimTime)
		{
        	//-- 动画循环处理
        	m_lastRootPos = m_rootBone.localPosition;
			print(m_lastRootPos);
			m_lastRootRot = m_rootBone.localRotation.eulerAngles;

        }
        else
        {
        	//-- 计算当前帧的Root Motion
        	Vector3 rootPos = m_rootBone.localPosition;
        	m_rootMotion = rootPos - m_lastRootPos;
        	m_lastRootPos = rootPos;
        

			Vector3 rootRot = m_rootBone.localRotation.eulerAngles;
			m_rootRot = rootRot - m_lastRootRot;
			m_lastRootRot = rootRot;
		
        }
		m_rootBone.localPosition = Vector3.zero;
		m_rootBone.localRotation = Quaternion.Euler(Vector3.zero);

        m_lastAnimTime = (int)animState.normalizedTime;
    }
}



mecanim参考程序:

using UnityEngine;
using System.Collections;

public class AnimatorTest_2 : MonoBehaviour 
{
	public Transform _rortBone;
	private Vector3 _startRootRot,_startRootRot2;
	private Vector3 _motionRootRot;

	private Animator _animator;
	private AnimatorStateInfo _animStateInfo;

	void Start()
	{
		_animator = GetComponent<Animator>();

		_startRootRot2 = _startRootRot = _rortBone.rotation.eulerAngles;
		_motionRootRot = Vector3.zero;
	}
	void Update()
	{
		_animStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
		AnimatorRecover();

		if(_animStateInfo.IsName("Base Layer.Idle"))
		{
			if(Input.GetKeyDown(KeyCode.A))
			{
				_animator.SetBool("IdleToLeft",true);
			}
			else if(Input.GetKeyDown(KeyCode.D))
			{
				_animator.SetBool("IdleToRight",true);
			}
		}

		if(_animStateInfo.IsName("Base Layer.TurnLeft") || _animStateInfo.IsName("Base Layer.TurnRight"))
		{
			transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles + _motionRootRot) ;
		}
	}
	void LateUpdate() 
	{
		if(_animStateInfo.IsName("Base Layer.TurnLeft") || _animStateInfo.IsName("Base Layer.TurnRight"))
		{
			print(_animStateInfo.normalizedTime);
			if(_animStateInfo.normalizedTime < 0.98f)
			{
				Vector3 _rootPos = _rortBone.localRotation.eulerAngles;
				_motionRootRot = _rootPos - _startRootRot;
				_startRootRot = _rootPos;

			}
			else
			{
				_motionRootRot = Vector3.zero;
				_startRootRot = _startRootRot2;
			}
			_rortBone.localRotation = Quaternion.Euler(Vector3.zero);
		}
	}	

	void AnimatorRecover()
	{
		if(!_animStateInfo.IsName("Base Layer.Idle"))
		{
			_animator.SetBool("IdleToRight",false);
			_animator.SetBool("IdleToLeft",false);
		}
	}


}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值