Unityのアニメーションイベントを使う

記事内に広告が含まれています。

今回はUnityのアニメーションイベントについてやっていきます。

すでにいくつもの記事でアニメーションイベントを使用した処理を記述していますが改めてアニメーションイベントに特化した記事を書こうと思いました。

アニメーションイベントは何に使えるかと言うと、例えば

  • キャラクターが歩いた時に足が地面に付いた時だけ足音を鳴らす。
  • キャラクターが剣を振った時の当たり判定のオン・オフをする。
  • キャラクターが剣を振る時に攻撃ボタンを押した時ではなく剣を振りおろすアニメーションの時に剣を振る効果音を鳴らす。
  • といった時に使え。

    剣を振った時が2項目ありますが、まぁスルーしていきましょう・・・・・(;一_一)

    スポンサーリンク

    サンプルのキャラクターを作成

    アニメーションイベントを使用する前にサンプルとして使用するキャラクターを作成します。

    この記事で作成するキャラクターはアニメーションイベントの確認の為に使用する為、多少作りこんだものになっています。

    今回の記事とは直接関係はないので無理に作って確認しなくてももっと簡易な方法で試してみてください。

    具体的なキャラクターの作り方は

    Unityでキャラクターの移動をプログラミングしてみる
    Unityで3Dキャラクターモデルを配置し、キャラクターをCharacterControllerの機能を使って移動させるようなプログラミングをしてみます。
    Unityでキャラクターがジャンプ出来るようにする
    Unityのゲームでキャラクターがジャンプ出来るようにする機能を作成します。
    Unityで主人公キャラが敵を攻撃出来るようにする機能
    Unityで主人公キャラが剣を振って敵キャラを攻撃出来るようにする機能を作成します

    を参照してください。

    StandardAssetsにあるモデルのEthanをシーンに配置しEthanのインスペクタにCharacterControllerコンポーネントを取りつけコライダのサイズを調整し、音声再生用のAudioSourceを取りつけます。

    AudioSourceのPlay On Awakeのチェックは外しておきます。

    EthanにはSaishouMoveCSharpというスクリプトを作成し取りつけます。

    スクリプトの具体的な解説は先ほど紹介した他の記事内でされているのでそちらを参照してください。

    とりあえずキャラクターが移動、ジャンプ、攻撃が出来るようにしたスクリプトになります。

    スクリプト名は毎度の事ながらご愛敬ということで・・・・・(^_^;)

    EthanのインスペクタのAnimatorに設定するAnimatorControllerは

    AnimationEvent用Animator

    Idle→RunはSpeedが0.1以上
    Run→IdleはSpeedが0.1以下
    Idle→JumpはJump
    Run→JumpはJump
    Jump→IdleはHas Exit Timeにチェックを入れ、アニメーションが終わったらIdleにいくようにする。
    Idle→AttackはAttack
    Run→AttackはAttack
    Attack→IdleはHas Exit Timeにチェックを入れ、アニメーションが終わったらIdleにいくようにする。

    のように条件を設定します。

    Attack状態のTagにはAttackを設定しておきます。

    アニメーションイベントの作成

    本当はここからが本題で、ここまでのキャラクター作りはおまけです。

    アニメーションイベント自体は簡単なものなので安心してください。(^_^)v

    走るアニメーションにアニメーションイベントを設定

    まずはキャラクターが歩いた時に足音を鳴らしたいのでAnimatorのRunに設定したアニメーションクリップにアニメーションイベントを設定していきましょう。

    Runに設定したアニメーションクリップを選択します。

    AnimationClipを選択

    ↑のように大元を選択します。

    インスペクタに

    AnimationClipのインスペクタ

    ↑のようにアニメーションのインポートセッティングが表示されます。

    今回の走るアニメーションは

    アニメーションイベント用の走るアニメーション

    ↑のような感じです。

    アニメーションのインポートセッティングで下の方にスクロールし、Events部分をクリックします。

    アニメーションイベントを作る

    ↑の赤い四角の中のボタンを押すとアニメーションクリップの再生位置にアニメーションイベントが作られます。

    現在のアニメーションの再生位置は下のウインドウで確認出来ますので、キャラクターが地面に足を付いた位置を調べそこにStepというアニメーションイベントを作成します。

    アニメーションが再生される下のウインドウの赤い縦線部分をクリックし足を着く位置を探します。

    0秒付近でも足を着いていますがこれはアニメーションの最後の足を着いた時の繋がりなので無視します。

    最初に足を着いた時

    ↑が最初に足をついた部分で0.08秒あたりです。

    ここで先ほどのアニメーションイベント作成ボタンを押すと、

    アニメーションイベントのウインドウ

    ↑のようにアニメーションイベント設定ウインドウが開きますのでFunctionのNewEventとなっている部分をStepに書き換えます。

    次に足を着く部分を探します。

    次に足を着いた時

    ↑のように0.16秒辺りですね。

    ここにアニメーションイベントを作成しFunctionをStepにします。

    アニメーションイベントStepを作成

    ↑がStepアニメーションイベントを設定した状態です。

    これで足を着いた時にStepというアニメーションイベントが発生するようになります。

    剣を振るアニメーションにアニメーションイベントを設定

    次に剣を振り初めの時にAttackStart、振り終わりの時にAttackEndというアニメーションイベントを作成し剣のコライダをオン・オフ出来るようにします。

    またAttackStartのタイミングで剣を振る音も再生するようにします。

    まずは剣を振り始めのアニメーションイベントを作成します。

    剣を振り始めのアニメーションイベント

    ↑のような位置でアニメーションイベントを作成しFunctionにAttackStartと入れます。

    次は剣を振り終わった時です。

    剣を振り終わりのアニメーションイベント

    ↑のような位置にAttackEndというアニメーションイベントを作成します。

    これで剣を振るアニメーションイベントの作成が終わりました。

    アニメーションイベントのレシーバースクリプトを作成

    アニメーションイベントは発生するようになりましたが、アニメーションイベントをスクリプトで受け取らなければいけません。

    アニメーションイベントはAnimatorと同じ階層に送られるので、Animatorが設定されているEthanにアニメーションイベント受け取り用のスクリプトを設定します。

    仮にアニメーション受け取り用のスクリプトを設定していないと、

    アニメーションイベントの受け取りスクリプトがない

    と、AnimationEventのレシーバーがないとエラーになります。

    アニメーションイベントの作成が出来たのでアニメーションイベントの受け取りスクリプトを作成しましょう。

    スクリプトはEthanに設定します。

    インスペクタで剣のコライダ、AudioSource、鳴らす効果音を設定出来るようにします。

    StepメソッドがアニメーションイベントのStepを受け取り実行される処理です。

    Stepを受け取ったら足音の効果音を鳴らします。

    AttackStartでは剣を振る効果音の再生と剣のコライダをオンにしています。

    AttackEndでは剣のコライダをオフにしています。

    こうすることで剣を振る前や剣を振り終わった後に敵との接触判定をしないようにする事が出来ます。

    今回の記事とは関係ないですが、コライダのオン・オフをしなくても変数としてフラグを用意しておき、剣の当たり判定部分でそのフラグを見て剣の当たり判定をするかどうかを判断する事も出来ます。

    例えばisColliderValidを用意し、

    AttackStartとAttackEndでフラグのオン・オフをし、剣が他のゲームオブジェクトと接触した時にIsColliderValidメソッドを使ってフラグの状態を見て、剣の当たり判定に利用します。

    こうすることでコライダのオン・オフと同じような事が出来ます。

    これでスクリプトが出来たのでEthanに取り付けパラメータを設定しましょう。

    ReceiveEventのインスペクタの設定

    Colにはキャラクターが持っている剣のコライダを設定し、AudioSourceには同じ階層に設定したAudioSourceを設定します。

    SeのSizeを2にしElement0には足音の効果音、Element1には剣を振る時の効果音を設定します。

    これで完成したのでUnityを実行し確認してみましょう。

    ↑のようにアニメーションイベントのタイミングで音声が鳴っています。

    スクリプトからアニメーションイベントを設定する

    ここまででアニメーションイベントの作り方とイベントの受け取りが出来ました。

    しかしアニメーションを他のキャラクターでも使いまわしをしていてアニメーションイベントが発生すると困る場合やアニメーションクリップ自体にアニメーションイベントを設定するのが嫌な場合はスクリプトからアニメーションイベントを設定する事も出来ます。

    スクリプトから剣を振り初めと走っている時の足音のアニメーションイベントを作成してみます。

    SaishouMoveCSharpに追記します。

    Animatorに設定されているアニメーションクリップの情報を全て取得し、そのクリップの中の剣をふるアニメーションの名前がAttack1のもの、MyRunのものを探します。

    剣を振るアニメーションクリップの名前がAttack1なので判定文字列にAttack1を使っています。

    剣を振るアニメーションクリップの名前がSword_Attackという名前ならば判定文字列もSword_Attackとします。

    attackClip、runClipにそのアニメーションクリップを保存しループを抜け出します。

    AnimationEventクラスをインスタンス化しアニメーションイベント名とアニメーションイベントが発生する時間を設定します。

    設定が終了したらAddEventを使用しそのアニメーションクリップにアニメーションイベントを設定します。

    attackClipにはアニメーションイベントを一つ付けるだけなのでAddEventを使っていますが、runClipには二つ付けるのでrunClip.eventsにアニメーションイベントの配列を入れる形で設定しています。

    これでスクリプトからUnity再生中のみアニメーションイベントを設定する事が出来ます。

    走って足をついた時の秒数を指定しましたが、どうにも実際とはズレてしまう為に実行しながらAnimationEventのtimeの値は調べました。

    スクリプトからアニメーションイベントを設定すれば手動でアニメーションイベントを設定し後が残るような事がないので他で使いまわしをしレシーバースクリプトがなくてもエラーになりません。

    ReceiveEventにメソッドを定義します。

    RunStepScriptEventメソッドでは現在再生しているアニメーションの再生時間を表示していますが、これは指定したアニメーションイベントの時間と実際のアニメーションクリップの時間がどうにも合わない為に表示してtimeの値を合わせるのに使った為です。

    それではAttackStartメソッド、Stepメソッドの中身をコメント化し実行してみましょう。

    ↑のようにスクリプトで設定したアニメーションイベントが実行されているのがわかります。

    ただしスクリプトで設定したアニメーションイベントは少し問題があります。

    手動で設定した時よりも正確なアニメーションの位置でイベントが発生していない感じがあります。

    今回の剣を振るアニメーション自体のアニメーションの長さが短いせいもあるかもしれませんが・・・・(^_^;)

    より正確な位置でイベントを発生させたい時は手動で細かく設定していった方がいいかもしれませんね。

    タイトルとURLをコピーしました