🦁

AnimationEventで地面に合わせた足音を鳴らす

2021/12/25に公開

AnimationEventを使って足音を鳴らしてみます。
ただ鳴らすだけでは面白くないので地面の種類が変わって鳴る音が変わるようにしてみたいと思います。
※Unityは2021.2.6f1を使っています

https://youtu.be/bkQwhBD3b_Q

シーン上のオブジェクト

  • AudioPlayer:AudioPlayerクラスとAudioSourceを持ち、音を鳴らすためのオブジェクト。
  • Utc_sum_humanoid:SDユニティちゃん。AnimationEventHookというAnimationEvent受け取るクラスを持つ。

AnimationEventを受け取るクラス

まずはAnimationEventを受け取るクラス(AnimationEventHook)を作成します。

using UnityEngine;

public class AnimationEventHook : MonoBehaviour
{
    [SerializeField]
    private AudioPlayer audioPlayer;

    // 鳴らす音の種類
    public AudioPlayer.eAundioType audioType;

    public void Step(AnimationEvent animationEvent)
    {
        // Intはどの音を鳴らすかのインデックス(AudioPlayerのAudioClipリストの再生するインデックス)
        int clipIndex = animationEvent.intParameter;

        audioPlayer.PlayAudioClip(audioType, clipIndex);
    }
}

このスクリプトをAnimatorのついているAnimationEventを発行するオブジェクトにつけます。
この例ではUtc_sum_humanoidのオブジェクトに追加します。

AnimationEventを受け取るクラスに必要な情報を先に渡しておけば音の種類を変えたり、音を鳴らさないようにしたり色々できます。

AnimationEventHookに鳴らす音の種類を渡せるようにして自動で鳴る音が変わるようにしています。
AnimationEventHookからAudioPlayerに設定している音を鳴らします。

AudioSouce再生クラス

AudioSourceを扱うクラスを作成します。
このクラスに鳴らす音の種類毎にどのAudioClipを再生するかを設定しておきます。

using System.Collections.Generic;
using UnityEngine;

public class AudioPlayer : MonoBehaviour
{
    [SerializeField]
    private AudioSource audioSource;

    [SerializeField]
    private List<AudioClip> floorAudioClips;

    [SerializeField]
    private List<AudioClip> gravelAudioClips;

    public enum eAundioType
    {
        Floor = 0,
        Gravel,
    }

    /// <summary>
    /// AudioClipを再生する
    /// </summary>
    /// <param name="audioType"></param>
    /// <param name="clipIndex">audioClipsリストの再生するインデックス</param>
    public void PlayAudioClip(eAundioType audioType, int clipIndex)
    {
        List<AudioClip> audioClips = new List<AudioClip>();
        switch (audioType)
        {
            case eAundioType.Floor:
                audioClips = floorAudioClips;
                break;

            case eAundioType.Gravel:
                audioClips = gravelAudioClips;
                break;
        }

        // 配列外チェック
        if (clipIndex < 0 || audioClips.Count <= clipIndex)
        {
            return;
        }

        audioSource.Stop();
        audioSource.clip = audioClips[clipIndex];
        audioSource.Play();
    }
}

AnimationEventの設定

AnimationにAnimationEventを追加し、AnimationEventに値を設定します。
Functionに呼び出し関数名、Intなどに必要なものを追加します。

今回はIntにAudioClipリストの再生するインデックスを渡しています。

AnimatorControllerにはAnimationをトリガーでアニメーションを再生できるように設定して試しました。

足音の変更

AnimationEventHookのaudioTypeを変更して足音を変更するのはここまでできていればいかようにでもできるかと思います。
例えばマップに指定しているColliderに入ったら変更するとか、自分の立っている座標から地面の種類を見て変更するとかですね。

まとめ

今回AnimationEventを使った足音の再生を行いました。
AnimatorControllerでやってますが、AnimationEventはAnimationに仕込むのでTimelineでも使えます。
AnimationEventを設定する箇所が使い勝手がかなり悪いです。
2019ではAnimationウィンドウでAnimationEventのコピペができなかったのができるようになったので改善は少しずつされているのかなと思います。

とはいえ使いこなせれば便利なので使いこなしていきたいですね。

Discussion