您的位置:首页 > 其它

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

2014-12-12 16:43 453 查看
【原文参考】/article/3583167.html

动画将控制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);
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: