動畫系統 關於動畫系統的根運動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);
		}
	}


}



發佈了48 篇原創文章 · 獲贊 15 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章