Animator のステートマシン
Assets/
Scenes/
Arena.unity
Scripts/
Animations/
すでにあるものこのレッスンで追加
Knight は PlayerMovement で動くようになりましたが、T ポーズのまま凍り付いて滑るように動いています。このレッスンでは足を与えます。
コードがクリップを直接再生することは決してありません。パラメータを設定するだけ——どのクリップを指すのかは Animator が決め、その間でブレンドします。
左のキャラクターが、右で光っている状態をそのまま演じるのを見てください——そして下にある 3 つのパラメータだけが、コードが触れる唯一のものです。
コントローラーをセットアップする
- 1
Project ビューで を選び、AC_Knight と名付けます。
- 2
Knight を選んで Animator コンポーネントを追加し、AC_Knight を Controller に、モデルの Avatar を Avatar へドラッグします。
- 3
ウィンドウを開き、Idle クリップをドラッグして入れましょう——オレンジ色のデフォルト状態になります。
- 4
Parameters tab で Speed(Float)、IsGrounded(Bool)、Attack(Trigger)を追加します。
歩行と走行を別々の状態にするより Blend Tree の方が得です
- 1
Animator 内で右クリック → Create State → From New Blend Tree。Locomotion と名付けてデフォルトにします。
- 2
それをダブルクリックし、Blend パラメータを Speed に設定してモーションを 3 つ追加します:Idle を 0、Walk を 2、Run を 6。
- 3
これで float ひとつが idle → walk → run を滑らかにクロスフェードします。移動のための遷移矢印は一切不要です。
コードから駆動する
using UnityEngine;
[RequireComponent(typeof(Animator))]
public class PlayerAnimator : MonoBehaviour
{
private Animator anim;
private CharacterController cc;
// hashes are faster than strings
private static readonly int SpeedHash = Animator.StringToHash("Speed");
private static readonly int GroundedHash = Animator.StringToHash("IsGrounded");
private static readonly int AttackHash = Animator.StringToHash("Attack");
void Awake()
{
anim = GetComponent<Animator>();
cc = GetComponent<CharacterController>();
}
void Update()
{
// horizontal speed only — vertical fall must not look like running
Vector3 flat = new Vector3(cc.velocity.x, 0f, cc.velocity.z);
anim.SetFloat(SpeedHash, flat.magnitude, 0.1f, Time.deltaTime); // 0.1f = damping
anim.SetBool(GroundedHash, cc.isGrounded);
if (Input.GetMouseButtonDown(0))
anim.SetTrigger(AttackHash);
}
}SetFloat の 3 番目と 4 番目の引数は damp 時間と delta time です:値が緩やかに変化するので、ブレンドがカクつきません。
Trigger は消費されると自動でリセットされる bool です。Attack のような一回きりのアクションに最適です。
StringToHash は static フィールドで一度だけ呼べば十分です:毎フレーム文字列で検索するのは無駄な作業です。
カクつきの 9 割を直す遷移設定
プレイヤー操作に即応すべき遷移(攻撃、ジャンプ)では Has Exit Time のチェックを外します。最後まで再生しきる必要があるアニメーションでは入れたままにしてください。
Transition Duration は 0.1〜0.2 秒が反応良く感じます。0.3 秒を超えるとキャラクターが酔っているような動きになります。
Interruption Source → Current State にすると、新しい攻撃が前の攻撃に割り込めるようになり、キュー待ちになりません。
Animation Events——剣を振ったその瞬間にヒットさせる
ダメージはボタンを押した瞬間ではなく、剣が本当に振り抜かれた瞬間に通すべきです。Animation Events を使えば、クリップの指定したフレームでメソッドを呼べます。
// on the same GameObject as the Animator
public void OnAttackHit() // pick this name in the clip's Events row
{
Debug.Log("hit frame");
// damage the enemies in range
}