Animation Eventとは?

Animation Eventは、アニメーション再生中の特定のタイミングでメソッドを呼び出すことができるUnityの機能です。

アニメーションのキーフレームに紐付けてイベントを設定することで、アニメーションとゲームロジックを同期させることができます。

例えば、歩行アニメーションで足が地面に着く瞬間に足音を再生したり、攻撃アニメーションの特定フレームで攻撃判定を発動したりできます。

Animation Eventを使うことで、アニメーションとスクリプトの連携がスムーズになり、より自然で洗練されたゲーム表現を実現できます。

Animation Eventの設定方法

Animation Eventは、Animationウィンドウから簡単に設定できます。

Animation Windowを開く

  1. イベントを設定したいアニメーションクリップを選択
  2. WindowAnimationAnimationでウィンドウを開く

イベントの追加

タイムライン上の任意の位置でイベントを追加できます。

  1. イベントを追加したいフレームをクリック
  2. イベントボタンをクリック、またはタイムライン上で右クリック → Add Animation Event
  3. Inspectorにイベントの設定項目が表示される

メソッド名の指定

InspectorFunctionフィールドに、呼び出したいメソッド名を入力します。

このメソッドは、アニメーションが設定されているGameObjectにアタッチされているコンポーネントに定義されている必要があります。

スクリプトでイベントを受け取る

Animation Eventで呼び出されるメソッドは、通常のMonoBehaviourのメソッドとして定義します。

基本的な実装

using UnityEngine;

public class CharacterController : MonoBehaviour
{
    // Animation Eventから呼ばれるメソッド
    private void OnFootstep()
    {
        Debug.Log("足音イベントが発生しました");
    }
}

重要なポイント:

  • メソッドはpublicまたはprivateどちらでも可
  • メソッド名はAnimation EventFunctionで指定した名前と一致させる
  • 同じGameObjectにアタッチされたコンポーネント内に定義する

シンプルな実装例

using UnityEngine;

public class PlayerAnimation : MonoBehaviour
{
    private void OnAttackStart()
    {
        Debug.Log("攻撃開始");
    }

    private void OnAttackHit()
    {
        Debug.Log("攻撃がヒット判定のタイミング");
    }

    private void OnAttackEnd()
    {
        Debug.Log("攻撃終了");
    }
}

実践例

足音の再生

歩行アニメーションで足が地面に着く瞬間に足音を再生します。

using UnityEngine;

public class FootstepSound : MonoBehaviour
{
    [SerializeField] private AudioSource _audioSource;
    [SerializeField] private AudioClip _footstepClip;

    // Animation Eventから呼ばれる
    private void PlayFootstep()
    {
        if (_audioSource != null && _footstepClip != null)
        {
            _audioSource.PlayOneShot(_footstepClip);
        }
    }
}

設定手順:

  1. 歩行アニメーションを開く
  2. 左足が地面に着くフレームと右足が地面に着くフレームにイベントを追加
  3. 両方のイベントのFunctionPlayFootstepを指定

攻撃判定の発動

攻撃アニメーションの特定フレームで攻撃判定を開始します。

using UnityEngine;

public class AttackController : MonoBehaviour
{
    [SerializeField] private Collider _weaponCollider;

    private void Start()
    {
        // 最初は攻撃判定を無効化
        if (_weaponCollider != null)
        {
            _weaponCollider.enabled = false;
        }
    }

    // 攻撃判定開始
    private void OnAttackStart()
    {
        if (_weaponCollider != null)
        {
            _weaponCollider.enabled = true;
        }
    }

    // 攻撃判定終了
    private void OnAttackEnd()
    {
        if (_weaponCollider != null)
        {
            _weaponCollider.enabled = false;
        }
    }
}

攻撃判定の実装:

using UnityEngine;

public class WeaponCollider : MonoBehaviour
{
    [SerializeField] private int _damage = 10;

    private void OnTriggerEnter(Collider other)
    {
        // 敵にダメージを与える
        var enemy = other.GetComponent<Enemy>();
        if (enemy != null)
        {
            enemy.TakeDamage(_damage);
            Debug.Log($"敵に{_damage}ダメージを与えました");
        }
    }
}

エフェクトの再生

攻撃やスキルのエフェクトをアニメーションと同期させます。

using UnityEngine;

public class EffectController : MonoBehaviour
{
    [SerializeField] private ParticleSystem _slashEffect;
    [SerializeField] private ParticleSystem _impactEffect;

    // 斬撃エフェクト再生
    private void PlaySlashEffect()
    {
        if (_slashEffect != null)
        {
            _slashEffect.Play();
        }
    }

    // 衝撃エフェクト再生
    private void PlayImpactEffect()
    {
        if (_impactEffect != null)
        {
            _impactEffect.Play();
        }
    }
}

ボイスの再生

キャラクターの掛け声やセリフをアニメーションと同期させます。

using UnityEngine;

public class VoiceController : MonoBehaviour
{
    [SerializeField] private AudioSource _audioSource;
    [SerializeField] private AudioClip[] _attackVoices;

    // ランダムな攻撃ボイスを再生
    private void PlayAttackVoice()
    {
        if (_audioSource != null && _attackVoices.Length > 0)
        {
            var randomIndex = Random.Range(0, _attackVoices.Length);
            _audioSource.PlayOneShot(_attackVoices[randomIndex]);
        }
    }
}

パラメータの渡し方

Animation Eventでは、メソッドに1つのパラメータを渡すことができます。

パラメータの種類

Animation Eventでサポートされているパラメータの型:

  • int - 整数値
  • float - 浮動小数点数
  • string - 文字列
  • Object - Unityオブジェクトへの参照

int型パラメータの例

using UnityEngine;

public class StepController : MonoBehaviour
{
    [SerializeField] private AudioClip[] _footstepSounds;
    [SerializeField] private AudioSource _audioSource;

    // int型のパラメータを受け取る
    private void PlayFootstep(int footIndex)
    {
        if (_audioSource != null && footIndex >= 0 && footIndex < _footstepSounds.Length)
        {
            _audioSource.PlayOneShot(_footstepSounds[footIndex]);
            Debug.Log($"足音{footIndex}を再生");
        }
    }
}

Animation Eventの設定で、Intフィールドに0(左足)または1(右足)を設定します。

float型パラメータの例

using UnityEngine;

public class FootstepVolumeController : MonoBehaviour
{
    [SerializeField] private AudioClip _footstepClip;
    [SerializeField] private AudioSource _audioSource;

    // float型のパラメータで音量を制御
    private void PlayFootstep(float volume)
    {
        if (_audioSource != null && _footstepClip != null)
        {
            _audioSource.PlayOneShot(_footstepClip, volume);
        }
    }
}

string型パラメータの例

using UnityEngine;

public class AnimationEventHandler : MonoBehaviour
{
    [SerializeField] private AudioSource _audioSource;

    // string型のパラメータで異なるサウンドを再生
    private void PlaySound(string soundName)
    {
        var clip = Resources.Load<AudioClip>($"Sounds/{soundName}");

        if (_audioSource != null && clip != null)
        {
            _audioSource.PlayOneShot(clip);
            Debug.Log($"{soundName}を再生");
        }
    }
}

Object型パラメータの例

using UnityEngine;

public class EffectSpawner : MonoBehaviour
{
    [SerializeField] private Transform _spawnPoint;

    // Object型のパラメータでエフェクトを生成
    private void SpawnEffect(GameObject effectPrefab)
    {
        if (effectPrefab != null)
        {
            var spawnPosition = _spawnPoint != null ? _spawnPoint.position : transform.position;
            Instantiate(effectPrefab, spawnPosition, Quaternion.identity);
        }
    }
}

複数の音を切り替える実装例

using UnityEngine;

public class SurfaceFootstep : MonoBehaviour
{
    [SerializeField] private AudioSource _audioSource;
    [SerializeField] private AudioClip _grassSound;
    [SerializeField] private AudioClip _woodSound;
    [SerializeField] private AudioClip _stoneSound;

    // 地面の種類に応じて足音を再生
    private void PlayFootstep(string surfaceType)
    {
        if (_audioSource == null) return;

        AudioClip clip = surfaceType switch
        {
            "Grass" => _grassSound,
            "Wood" => _woodSound,
            "Stone" => _stoneSound,
            _ => null
        };

        if (clip != null)
        {
            _audioSource.PlayOneShot(clip);
        }
    }
}

注意点

メソッドのアクセス修飾子

Animation Eventで呼び出すメソッドは、publicまたはprivateどちらでも機能します。

外部から呼ばれることがない場合は、privateにすることを推奨します。

// どちらでも動作する
public void OnEvent() { }
private void OnEvent() { }

同じGameObjectにアタッチされたコンポーネントのみ

Animation Eventは、アニメーションが設定されているGameObjectにアタッチされているコンポーネントのメソッドのみ呼び出せます。

子オブジェクトや親オブジェクトのメソッドを直接呼ぶことはできません。その場合は、以下のように親からメソッドを呼び出します。

using UnityEngine;

public class CharacterAnimation : MonoBehaviour
{
    private CharacterController _controller;

    private void Start()
    {
        // 親オブジェクトのコンポーネントを取得
        _controller = GetComponentInParent<CharacterController>();
    }

    // Animation Eventから呼ばれる
    private void OnAttack()
    {
        // 親オブジェクトのメソッドを呼び出す
        _controller?.ExecuteAttack();
    }
}

パラメータは1つまで

Animation Eventでは、1つのメソッドに渡せるパラメータは1つだけです。

// ✅ OK: パラメータ1つ
private void PlaySound(string soundName) { }

// ❌ NG: パラメータ2つは使えない
private void PlaySound(string soundName, float volume) { }

複数の値を渡したい場合は、構造体や文字列を使って工夫します。

// 文字列を分割して複数の情報を渡す
private void PlaySound(string parameters)
{
    var parts = parameters.Split(',');
    var soundName = parts[0];
    var volume = float.Parse(parts[1]);

    // サウンド再生処理
}

メソッド名のタイポに注意

Animation EventFunctionフィールドに指定したメソッド名が、実際のメソッド名と一致していない場合、エラーは発生しませんが、メソッドが呼ばれません。

// スクリプト側
private void OnFootStep() { }  // 大文字のS

// Animation Event側
Function: OnFootstep  // 小文字のs

// → 呼ばれない(タイポ)

パフォーマンスへの配慮

Animation Eventは、アニメーションの再生中に頻繁に呼ばれる可能性があります。重い処理を直接実行すると、フレームレートが低下する恐れがあります。

// ❌ 悪い例: 重い処理を直接実行
private void OnFootstep()
{
    // 毎回検索するのは重い
    var audioSource = GameObject.Find("AudioManager").GetComponent<AudioSource>();
    audioSource.Play();
}

// ✅ 良い例: 事前にキャッシュ
[SerializeField] private AudioSource _audioSource;

private void OnFootstep()
{
    _audioSource.Play();
}

アニメーションの速度変更に対応

Animatorspeedを変更した場合でも、Animation Eventは正しいタイミングで発火します。

// アニメーション速度を2倍にしても、イベントは正しいタイミングで発火する
animator.speed = 2f;

まとめ

Animation Eventは、アニメーションとゲームロジックを同期させる強力な機能です。

足音、攻撃判定、エフェクト再生など、アニメーションの特定フレームで何かを実行したい場合に非常に便利です。

設定も簡単で、Animationウィンドウからイベントを追加し、スクリプトでメソッドを定義するだけで使えます。

パラメータを使えば、同じメソッドで異なる動作をさせることもでき、柔軟な実装が可能です。

ただし、パラメータは1つまでという制限や、同じGameObjectのコンポーネントにしかアクセスできないという制約には注意が必要です。

ぜひAnimation Eventを活用して、アニメーションとロジックが美しく連携したゲームを作ってください!