バッテラが如く

プログラミングしましょ!

【Unity】アニメーション(モーション)をスクリプトで動的に再生させる方法

この記事の情報は次のバージョンで動作確認しています。

  • MacOS Monterey (12.1)
  • Unity (2021.3.2f1)
  • Unity

    はじめに

    どうも、バッテラです。

    以前キャラクターに歩くモーションをつけて動かすまでというのをやりました。

    www.m2game.net

    次のステップとしてはトリガーを用意して指定モーションを再生できるようにすることだと思います。

    Aモーション(ループ)中にトリガー発動 → Bモーション再生 → Aモーション再生を実装してみます。

    準備

    今回もmixamoにあるモーションを使います。なんでもいいですが「THANKFUL」というモーションを追加モーションとして使いたいと思います。

    これをAnimatorControllerに配置してこの状態にします。

    とりあえずこれで準備は完了です。

    トリガーを作る

    別モーションに切り替えするにはトリガーを作る必要があります。

    トリガーは Parametersタブで作成することができます。

    +ボタンをクリックしてTriggerを選択します。

    トリガー名はスクリプトで使うのでちゃんとしましょう
    ※日本語は入力できなかったです。

    トランジションを作る

    次はトランジションを作ります。トランジションというのはEntityの移動のことを言います。

    トリガーがオンになったら別モーションにトランジションさせるようにしていきます。

    移動前のEntityで右クリック → Make Transitionとします。 移動後のEntityに矢印を結びます。

    これで再生すると・・・

    ループしていた歩きモーションが1ループで終わり、新しいモーションに切り替わります。

    これは静的にトランジションしてしまっているのでだめですね。

    トランジションの発動条件を作る

    動的なトランジションをするにはトランジションに条件を持たせる必要があります。

    そこで使うのは先ほど作ったトリガーです。

    まずトランジションをクリックしインスペクター画面を表示します。

    Conditionsまで下にスクロールします。

    +ボタンをクリックしトリガーをセットします。

    この状態で再生してみると・・・

    歩くモーションだけがループしている状態になりましたね。これでOKです。

    規定のモーションに戻す

    次は新しいモーションが終わった時に規定のモーションに戻してあげるというのをやります。

    これもトランジションを作ることでできます。

    移動後のEntityで右クリック → Make Transitionとします。 移動前のEntityに矢印を結びます。

    そうすると双方向の矢印ができた状態になります。

    移動後のモーションにはトリガーはいらないのでこれで戻りが完成です。

    エディタ上でトリガーの確認しよう

    Unityプレイヤーで実行している時にAnimator画面を開くと動作状況が可視化されます。

    ヒエラルキーウィンドウでそのゲームオブジェクトを選択している必要あり

    デバッグはこれでやるのがよさそうですね!

    さらにトリガーを発動させるのもエディタ上でできます。それをやるにはParamatersタブを開いて状態にします。

    ○の部分をチェックするとトリガー発動となります。

    これでトリガーオンにすると別のモーションにいくことが確認できました。

    モーション中でも強制的に次のモーションに移行する

    先ほどの映像だと少し分かりづらかったと思いますが、トリガーをオンにしても実際にトランジションが発動するのはモーションを終わってからになってます。

    これをモーションの終わりを待たずに切り替えるには、

    トランジションのインスペクタを開き、[Has Exit Time]のチェックを外します。

    これでモーション中にトランジションさせることができました。

    スクリプトでトリガーを発動させる

    ようやく本題w

    最後にスクリプトで制御していく処理を実装していきます。

    Animatorコンポーネントがアタッチされているキャラクターにスクリプトを追加しましょう。

    トリガーを発動したいタイミングでこのように実装します。

    Animator _animator = GetComponent<Animator>();
    
    _animator.SetTrigger("トリガー名");
    

    コード全文だとこのようになります。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    [RequireComponent(typeof(Animator))]
    public class Spike : MonoBehaviour
    {
       
    
        // Start is called before the first frame update
        void Start()
        {
            
        }
    
        // Update is called once per frame
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.Alpha1))
            {
                Animator _animator = GetComponent<Animator>();
    
                _animator.SetTrigger("Pose");
            }
        }
    }
    

    とりあえずテストとして1キー押したらトリガーを発動させるようにしてみました。

    最後にUnityプレイヤーで動作を確認します。

    いい感じ♪に動きましたー。

    おしまい。

    あとがき

    ループよりトランジションが優先されるということが知れてよかった。