【Unity】Animation Event・Root Motion・IK:アニメとゲームを同期させる3つの道具

作成: 2026-07-16

モーションは再生できる。でも「振り下ろした瞬間にダメージを出す」「踏み込みと移動を一致させる」「手を壁にぴたりと合わせる」になると急に難しくなる——アニメーションとゲーム世界の同期の問題です。モーションの特定フレームでコードを呼ぶAnimation Event、移動をアニメに任せるRoot Motion、手足を対象へ吸着させるIKの3つを、使いどころ・落とし穴・実戦コードつきで解説し、踏み込み斬りを完成させます。

Animatorの基礎3Dキャラの実践 で、モーションは再生できるようになりました。でも次の要求で、急に手が止まります。「 剣を振り下ろした瞬間 にだけダメージを出したい」「攻撃の 踏み込みの移動 をアニメ通りにしたい」「はしごや壁に 手をぴたりと合わせたい 」——再生はできても、 アニメとゲーム世界が同期していない のです。

この同期問題を解くのが、今回の3つの道具です。 Animation Event(タイミングの同期)、 Root Motion(移動の同期)、 IK(接触の同期)。それぞれの使いどころと落とし穴を押さえて、最後は「踏み込み斬り」を完成させます。

モーションとゲーム処理が同期するイメージ

この記事でわかること

  • 3つの道具の役割分担( タイミング・移動・接触
  • Animation Event でモーションの特定フレームにコードを呼ぶ
  • Root Motion をオンにする場面・オフにする場面・OnAnimatorMove の折衷
  • IK で手を対象へ吸着させる(OnAnimatorIK
  • 実践:Root Motion+Animation Eventで 踏み込み斬り を組む

動作確認環境: Unity 2022.3 LTS / Unity 6・Humanoidリグ

Sponsored

3つの道具の役割分担

3つとも「アニメーションとゲーム世界のズレを埋める」道具ですが、埋めるズレの種類が違います。

Animation Event・Root Motion・IKの役割分担図。Animation Eventはモーションの瞬間とコードのタイミングを、Root Motionはモーションの移動量とキャラの位置を、IKは手足の位置と世界の対象物を同期させる
道具同期させるもの代表的な用途
Animation Eventタイミング(この瞬間に処理を呼ぶ)攻撃判定の窓・足音・エフェクト
Root Motion移動(アニメの移動量=キャラの移動量)踏み込み・回避ロール・演出
IK接触(手足の位置=世界の対象物)壁に手をつく・レバーを掴む・足の接地

「どれを使うべきか」で迷ったら、 何がズレているのか を言葉にしてください。タイミングがズレているならEvent、移動距離がズレているならRoot Motion、手足の位置がズレているならIK——それだけで道具は決まります。

Animation Event:モーションの瞬間にコードを呼ぶ

「振り下ろしの瞬間」をコードのタイマーで合わせようとすると、WaitForSeconds(0.37f) のようなマジックナンバーが生まれ、モーションを差し替えるたびに壊れます。正解は逆で、 モーション側に「この瞬間」の目印を打ち、そこからコードを呼びます。それがAnimation Eventです。

Animation Eventの図。攻撃モーションのタイムライン上の振り下ろしのフレームにイベントマーカーが打たれ、そこからOpenHitWindowという関数が呼ばれる

打ち方は、対象のアニメーションクリップを選んで Animationウィンドウ(またはモデルのImport SettingsのAnimationタブ > Events)を開き、狙いのフレームで イベント追加ボタン を押して、呼びたい 関数名 を指定するだけです。受け側はこうなります。

// AttackEventReceiver.cs — Animatorと同じGameObjectに付ける
using UnityEngine;

public class AttackEventReceiver : MonoBehaviour
{
    [SerializeField] private SwordHitbox hitbox;
    [SerializeField] private AudioSource footstepSource;

    // 振り下ろし開始のフレームから呼ばれる
    public void OpenHitWindow()
    {
        hitbox.Swing();
    }

    // 歩きモーションの着地フレームから呼ばれる(footstepイベント)
    public void PlayFootstep()
    {
        footstepSource.Play();
    }
}

ここに落とし穴が2つあります。 呼び出し先はAnimatorと同じGameObject上のpublicメソッド に限られること。そして 関数名のタイプミスはエラーにならない こと——Consoleに警告が出るだけで、静かに無反応になります。「イベントが呼ばれない」ときは、まずこの2点です。

SwordHitbox に見覚えがあるでしょうか。ダメージ処理の記事 で作った「判定窓」を、コルーチンの固定秒数ではなく モーションの実フレーム で開閉できるようになった——これがAnimation Eventの実戦価値です。

Root Motion:移動をアニメに任せる

歩きモーションには本来「前に進む」movementが焼き込まれています。 Root Motion はこの移動量をそのままキャラクターの位置に反映する仕組みで、AnimatorコンポーネントのApply Root Motionで切り替えます。

Root Motionの比較図。オンではアニメーションの踏み込みの移動量がそのままキャラの位置に反映されて見た目と移動が一致し、オ�フではその場でモーションだけ再生されコードが別途移動を担当する

使い分けの感覚はこうです。

  • オンが向く: 攻撃の踏み込み、回避ロール、フィニッシュ演出——「 この移動はアニメーターが設計した距離で動いてほしい 」場面。見た目と移動が絶対にズレません
  • オフが向く: 通常の走り回り——「 入力に機敏に反応する操作感 」が欲しい場面。CharacterController や Rigidbody で速度を直接制御する方が、ゲームらしいキビキビ感が出ます

そして実戦でいちばん使うのが折衷案です。 OnAnimatorMove() を書くと、Root Motionの移動量を「受け取ってから、自分で適用」できます

// RootMotionReceiver.cs — Animatorと同じGameObjectに付ける
using UnityEngine;

[RequireComponent(typeof(CharacterController))]
public class RootMotionReceiver : MonoBehaviour
{
    private Animator animator;
    private CharacterController controller;

    void Awake()
    {
        animator = GetComponent<Animator>();
        controller = GetComponent<CharacterController>();
    }

    // これを書くと、Root Motionの自動適用の代わりにここが呼ばれる
    void OnAnimatorMove()
    {
        // アニメ由来の移動量を受け取る
        Vector3 delta = animator.deltaPosition;

        // 高さはアニメに任せず、重力は自前の仕組みで管理する
        delta.y = 0f;

        controller.Move(delta);
        transform.rotation *= animator.deltaRotation;
    }
}

「水平移動はアニメの踏み込み通り、重力と接地は自前」——Root Motionの説得力とコード制御の安定を両取りする、定番の書き方です。

Sponsored

IK:手足を世界に合わせる

アニメーションクリップは「収録したときの世界」で作られています。実際のゲームでは壁の位置もレバーの高さも毎回違う——だから「手を伸ばすモーション」を再生しても、手は対象から数センチ浮きます。この最後の数センチを埋めるのが IK(Inverse Kinematics) です。ゴール(手の目標位置)を指定すると、肘や肩の角度をUnityが逆算して、手をぴたりと合わせます。

IKの比較図。IKなしでは手を伸ばすモーションの手が壁から浮いているが、IKで手のゴールを壁の位置に指定すると腕の関節が逆算されて手のひらがぴたりと壁につく

準備は2つ。モデルが Humanoidリグ であること、Animator Controllerの対象レイヤー設定(歯車アイコン)で IK Pass にチェックを入れることです。すると OnAnimatorIK() が呼ばれるようになります。

// HandIK.cs — Animatorと同じGameObjectに付ける
using UnityEngine;

public class HandIK : MonoBehaviour
{
    [SerializeField] private Transform target;   // 触れたい対象(壁のポイントなど)
    [SerializeField, Range(0f, 1f)] private float weight = 1f;

    private Animator animator;

    void Awake()
    {
        animator = GetComponent<Animator>();
    }

    // IK Passが有効なとき、毎フレーム呼ばれる
    void OnAnimatorIK(int layerIndex)
    {
        if (target == null) return;

        // 右手のゴールを対象へ。weightが0なら元のアニメのまま、1なら完全に吸着
        animator.SetIKPositionWeight(AvatarIKGoal.RightHand, weight);
        animator.SetIKPosition(AvatarIKGoal.RightHand, target.position);
    }
}

コツは weightを瞬間的に1にしない ことです。0→1へ短時間で補間すると「自然に手が吸い付く」動きになり、対象から離れるときは1→0へ戻します。ドアノブ、レバー、壁への手つき——「世界に触れる」動きの説得力が一段変わります。

実践:踏み込み斬りを組む

3つの道具のうち2つ——Root MotionとAnimation Event——を組み合わせて、アクションゲームの基本形 「踏み込み斬り」 を完成させます。前へグッと踏み込みながら振り下ろし、刃が走る瞬間だけ判定が開く。ソウルライクの強攻撃、無双系のチャージ斬り、アクションRPGの通常コンボ——全部この骨格です。

踏み込み斬りの場面図。クレイ人形が剣を振り下ろしながら大きく前へ踏み込み、移動の軌跡がアニメ由来であることを示す足元の矢印と、振り下ろしの瞬間にだけ開く判定�の扇形が描かれている

組み立ては4手順です。

  1. 攻撃ステートのモーションにRoot Motionを効かせる: 踏み込みの移動量が焼き込まれた攻撃クリップを使い、先ほどの RootMotionReceiver で水平移動だけアニメに任せます。「コードで前進させながら攻撃モーション再生」でありがちな、 足が滑る踏み込み が消えます
  2. クリップにAnimation Eventを2つ打つ: 振り下ろし開始のフレームに OpenHitWindow、振り抜き終わりに CloseHitWindowSwordHitbox 側に窓を閉じるメソッドを1つ足してください)。判定の開閉が モーションの実フレームに固定 されます
  3. 攻撃中は移動入力を切る: Stateパターン の攻撃ステートに入ったら通常移動を止め、位置の主導権をRoot Motionへ渡します。二重の移動が混ざるのを防ぐ、Root Motion運用の基本作法です
  4. Playで検証する: 敵の手前で攻撃→踏み込みで間合いが詰まり、刃が走る瞬間だけHPが減ることを確認します

わざと壊してみると、この構成の意味が見えます。Animation Eventを消してコルーチンの固定秒数に戻すと、攻撃モーションを速いものに差し替えた瞬間、 振り終わった後に判定が開く ズレが生まれます。Root Motionを切ってコード移動に戻すと、踏み込みの見た目と実際の移動距離が合わず、 足が滑って間合いが狂います。2つの道具は、それぞれのズレをちょうど塞いでいたわけです。

ポイントは2つ。 タイミングはモーション側に打つ(コードの秒数で追いかけない)。 移動の主導権は場面ごとに1つ(攻撃中はRoot Motion、通常時はコード。混ぜるなら OnAnimatorMove で明示的に)。

おまけ:先に知っておくと良いこと

  • 足の接地(Foot IK): 坂や階段で足が地面にめり込む・浮く問題は、足向けのIKで解決します。ステートのFoot IKチェックとカーブ設定を使う標準の仕組みもありますが、本格的には次項のAnimation Riggingが扱いやすいです
  • Animation Riggingパッケージ: この記事のIKはHumanoid組み込みの基本形です。銃を両手で構える、視線を追うなど本格的なリグ制御は、公式の Animation Riggingパッケージ が上位互換の選択肢になります
  • カットシーンはTimelineへ: 「決まった尺の演出の中でキャラを動かす」なら、ステートマシンより Timeline が適任です。Root Motionとの主導権の考え方はTimelineでも同じです

まとめ

  • 3つの道具は同期のズレ別に選ぶ: タイミング=Animation Event、移動=Root Motion、接触=IK
  • Animation Eventは 同じGameObject上のpublicメソッド を呼ぶ。タイプミスは警告だけで無反応
  • Root Motionは踏み込み・ロール・演出に。操作感重視の移動はコードで。折衷は OnAnimatorMove
  • IKは Humanoid+IK PassOnAnimatorIK を有効化し、 weightの補間 で自然に吸着させる
  • 踏み込み斬り= Root Motionの移動+Animation Eventの判定窓。コードの秒数で追いかけない

あなたのゲームの攻撃モーション、判定の開閉はいまも WaitForSeconds で数えていませんか? モーションに目印を打つ側へ引っ越すと、アニメ差し替えが怖くなくなります。