フットスライディング(足滑り)
キャラクターの動く速度と、アニメーションが同期してない場合に、
フットスライディング(足滑り)が起こります。
こんな感じに、リアルで「地に足がついている」ように見せる方法を紹介します。
※ キャラクターををお借りしました
Sci-Fi Soldier
解決方法
前提として、3DCGソフト側でモーションに合わせて実際に移動させておきます。
その移動量を使って、ゲーム中の移動とアニメーションを同期させます。
using UnityEngine;
// Enable animator ApplyRootMotion
// Add movement amount of Z in animation
public class CharacterController : MonoBehaviour
{
[SerializeField]
float _moveSpeed;
Animator _animator;
float _movementInWalk;
private static readonly int _walkNameHash = Animator.StringToHash("Walk");
// Use this for initialization
void Start()
{
_animator = GetComponent<Animator>();
_movementInWalk = ExamineMovement(_walkNameHash);
Walk();
}
void OnAnimatorMove()
{
// Update movement in animation
var deltaPos = _animator.deltaPosition;
transform.localPosition += deltaPos;
}
// Measure the amount of movement to the Z axis during animation
private float ExamineMovement(int nameHash)
{
_animator.Play(nameHash);
_animator.Update(0f);
var currentClip = _animator.GetCurrentAnimatorClipInfo(layerIndex: 0)[0].clip;
_animator.Update(currentClip.length);
var movement = Vector3.Project(_animator.deltaPosition, transform.forward).magnitude / currentClip.length;
return movement;
}
private void Walk()
{
_animator.speed = _moveSpeed / _movementInWalk; // Adjust the animation speed according to the moving speed
_animator.PlayInFixedTime(_walkNameHash, layer: 0, fixedTime: 0f);
}
}
ExamineMovement
メソッドでアニメーション中での移動量を計測しています。
(ここではZ軸の移動量のみを対象にしています)
Walk
メソッドで、アニメーションの再生速度を調整しています。
ゲーム中での移動量と、アニメーション中での移動量が同期するように、再生速度を設定しています。
OnAnimatorMove
メソッドをオーバーライドして、アニメーション中の移動量をゲームにそのまま反映します。