見出し画像

【Unity初心者向け】Animator基礎編③|TriggerとAny Stateで攻撃アニメーションを作る

前回は、Animatorで利用できるParameterについて確認しました。

AnimatorのParameterには、

  • Bool

  • Float

  • Int

  • Trigger

という4種類があります。
今回はその中から、Triggerを実際に使ってみます。

Triggerは、攻撃やダメージなど「一度だけ実行したい動作」をAnimatorへ伝えるときに便利なParameterです。

さらに今回は、Animatorに最初から用意されている「Any State」も利用します。
Any Stateを使うと「Idle中でもWalk中でも、攻撃ボタンを押したらAttackへ切り替える」といった処理を簡単に作ることができます。

今回は、TriggerとAny Stateを使って攻撃アニメーションへ切り替える方法を確認していきましょう。

Animator 基礎編【全5回】

  1. Animatorとは? ― IdleとWalkを切り替える

  2. Parameterの使い方 ― Bool / Float / Int / Trigger

  3. TriggerとAny State ― 攻撃アニメーションを作る

  4. Transitionを理解する ― Has Exit Time / Duration

  5. Animation Event ― アニメーションから処理を呼び出す



今回作るもの

これまでの記事では、Idle ⇄ Walk という形で、待機状態と歩行状態を切り替えてきました。
今回はここへ、Attack を追加します。

例えばIdle状態のときに攻撃ボタンを押したら、Idle → Attack へ切り替えます。
もちろん、Walk中にも攻撃できるようにしたいので、Walk → Attack と切り替えます。
さらに今後、

  • Run

  • Jump

  • Crouch

などのStateが増えたとしても、それぞれの状態から攻撃できるようにしたいですよね。

そこで利用するのが、今回のテーマでもある Any State です。


Triggerとは?

まずはTriggerについて簡単におさらいしておきましょう。

Triggerは、Animatorへ一度だけ合図を送るParameterです。
例えば、

  • 攻撃する

  • ジャンプする

  • ダメージを受ける

  • アイテムを使う

といった、その瞬間に一度だけ実行したい動作に向いています。

前回確認したBoolとは、この点が少し違います。


BoolとTriggerの違い

例えばBoolを使って、

animator.SetBool("Walk", true);

とすると、

Walk = true

という状態がそのまま残ります。

animator.SetBool("Walk", false);

のように、必要に応じて false へ戻さない限り、true の状態が続きます。

一方、Triggerでは、

animator.SetTrigger("Attack");

とします。
これは「Attackして!」という合図を一度だけAnimatorへ送るイメージです。

Triggerは、AnimatorのTransitionで利用されると、その合図が消費されます。
そのため「攻撃中かどうか」という状態を保存しておくというより、「今、攻撃して」というタイミングを伝えるのに向いています。


Attackアニメーションを用意する

それではAnimatorへAttackを追加していきます。

今回は、攻撃用のAnimation Clipがすでに用意されているものとして進めます。
サンプルでは前回使用した「Ninja Sprite Sheet」というAssetをお借りして、ソードを振るAnimationClipを作ってみました。
AnimationClip の Loop Time のチェックを外しておくと、1回だけの処理になります。

AnimatorウィンドウへAttack用Animation Clipをドラッグすると、

Attack

というStateが作成されます。

現在のAnimator Controllerは、

Idle
Walk
Attack

という3つのStateがある状態です。

IdleとWalkについては、これまでの記事で作成したものをそのまま利用します。


Trigger Parameterを作成する

次にTrigger Parameterを作ります。

Animatorウィンドウ左側にある、Parameters を確認してください。
「+」ボタンをクリック ⇒ Trigger を選択します。
今回は名前を「Attack」とします。

これでAnimatorへ、Attack というTrigger Parameterが追加されました。


Any Stateとは?

次にAny Stateを使います。

Animator Controllerを見ると「Any State」というStateが最初から用意されています。

Any Stateは名前のとおり「どのStateにいるときでも」という意味で考えると分かりやすいでしょう。

例えば通常のTransitionでAttackへつなぐ場合、Idle → Attack を作ります。さらにWalkからも攻撃したければ、Walk → Attack も必要です。
Runが増えれば、Run → Attack も必要になります。
Stateが増えるたびにTransitionも増えてしまいます。

そこで、Any State → Attack というTransitionを1本作っておけば、どのStateからでもAttackへ移動できるようになります。


Any StateからAttackへTransitionを作る

  1. Animatorウィンドウで「Any State」を右クリック

  2. 「Make Transition」を選択

  3. そのまま「Attack」をクリック

これで、Any State → Attack というTransitionが作成されます。


ConditionへAttack Triggerを設定する

Transitionを作っただけでは、いつAttackへ切り替えるのか分かりません。

そこでConditionを設定します。
Any State → Attack のTransitionを選択してください。

Inspectorの、Conditions へ、Attack を追加します。

これで、Attack Triggerを受け取ったときにAttackへ移動するというTransitionになります。


スクリプトからTriggerを送る

それでは、スクリプトからAttack Triggerを送ってみましょう。

今回は分かりやすく、Spaceキーを押したら攻撃という処理にします。

public class PlayerAnimatorController : MonoBehaviour
{
    Animator animator;  // Animatorコンポーネントを格納する変数

    void Awake()
    {
        animator = GetComponent<Animator>();    // Animatorコンポーネントを取得
    }

    void Update()
    {
        float x = Input.GetAxisRaw("Horizontal");   // 水平方向の入力を取得

        if (x != 0) // 入力がある場合、
        {
            animator.SetBool("isWalking", true);    // 歩行アニメーションを再生
        }
        else       //入力がない場合、
        {
            animator.SetBool("isWalking", false);   // 歩行アニメーションを停止
        }
        //ここまで基礎編①で作成済み

        if (Input.GetKeyDown(KeyCode.Space)) // スペースキーが押されたとき
        {
            animator.SetTrigger("Attack");  // Attackトリガーを発動
        }
    }
}

今回重要なのは、

animator.SetTrigger("Attack");

です。


SetTrigger()とは?

animator.SetTrigger("Attack");

の、SetTrigger() は、AnimatorのTriggerを動かす命令です。
今回であれば、Attack というTriggerへ合図を送っています。

Animator側では、Attack Trigger が送られると  Any State → Attack というConditionを設定しているため、Attack Stateへ切り替わります。

つまり、

animator.SetTrigger("Attack");

と、Animator Controller側の、

Condition:Attack

がセットになっています。


GetKeyではなくGetKeyDownを使う

今回のスクリプトでは、

Input.GetKeyDown(KeyCode.Space)

を使っています。
例えば、

Input.GetKey(KeyCode.Space)

を使った場合、Spaceキーを押している間ずっと処理が実行されます。

一方

Input.GetKeyDown(KeyCode.Space)

は、キーを押した瞬間だけ true になります。

今回は「キーを押した瞬間に1回だけ攻撃する」という処理なので、GetKeyDownが適しています。


Idle中に攻撃してみる

まず何も操作していないIdle状態で「Spaceキー」を押してみます。

すると、Idle → Attack と切り替わります。
Triggerが送られ、Any State → Attack のConditionが成立したためです。


Walk中にも攻撃できる

次に、PlayerをWalk状態にします。

その状態で「Spaceキー」を押してみましょう。
今度は、Walk → Attack と切り替わります。
IdleからAttackへ直接Transitionを作っていなくても問題ありません。
Any Stateを利用しているため、現在のStateに関係なくAttackへ移動できるからです。


Attackが終わったらどうする?

ここまでで、Any State → Attack は作れました。

しかし、このままではAttack Stateへ移動したあと、元の状態へ戻る処理がありません。

そこで、Attack → Idle というTransitionも作っておきます。
今回は、攻撃アニメーションが最後まで再生されたらIdleへ戻る という形にしてみます。

  1. Attackを右クリックし「Make Transition」を選択

  2. そのままIdleへつなぐ

これで、Attack → Idle が作成されます。


Has Exit Time

AttackからIdleへ戻るTransitionを見ると「Has Exit Time」という項目があります。

Has Exit Timeを利用すると、アニメーションが一定の位置まで再生されてから次のStateへ移動するという動きを作ることができます。

攻撃アニメーションの場合、攻撃途中なのにIdleへ戻るよりも、攻撃アニメーションを最後まで再生後にIdleへ戻るのほうが自然です。

そのためHas Exit Timeがよく利用されます。
ただし、このHas Exit Timeについては設定項目がいくつかあります。

次回の、Animator基礎編④「Transitionを理解する」で詳しく確認します。

今回は、Attack終了後にIdleへ戻すために利用できるということだけ覚えておけば十分です。


Any Stateは攻撃以外にも使える

Any Stateは攻撃専用の機能ではありません。

例えばダメージを受けたときにも便利です。
Any State → Damage としておけば、Idle中でもWalk中でも、

animator.SetTrigger("Damage");

を実行することでDamageアニメーションへ移動できます。
同じように、Any State → Death として、

animator.SetTrigger("Death");

とすれば、死亡アニメーションへ切り替えることもできます。


Any Stateと相性の良い動作

Any Stateは特に、

  • Attack

  • Damage

  • Death

など、現在のStateとは関係なく発生する動作との相性が良い機能です。

例えば、

  • Idle

  • Walk

  • Run

のどこにいても、敵から攻撃を受ける可能性があります。
このような場合、

  • Idle → Damage

  • Walk → Damage

  • Run → Damage

と1本ずつTransitionを作るより、

  • Any State → Damage

としたほうがシンプルです。


TriggerとAny Stateの役割を整理しよう

ここまでの流れを整理すると、まずスクリプト側で、

animator.SetTrigger("Attack");

を実行します。
すると、Attack Trigger がAnimatorへ送られます。

Animatorでは、Any State → Attack のTransitionに、「Condition:Attack」が設定されています。

そのため、

  1. どのStateにいる場合でも

  2. Attack Triggerを受け取る

  3. Attackへ移動

という動きになります。
TriggerとAny Stateは、それぞれ別の機能ですが、組み合わせて使うことで非常に便利になります。


次回は……

今回は、Any State → Attack というTransitionを作りました。

しかし、Animatorを実際に使っていると、

  • 攻撃アニメーションが終わる前にIdleへ戻る

  • なかなか次のStateへ切り替わらない

  • Stateが切り替わるときに動きが不自然になる

といった問題が出てくることがあります。

これらに大きく関係しているのが、

Has Exit Time
Transition Duration

などのTransition設定です。

次回の、
Animator基礎編④「Transitionを理解する ― Has Exit Time / Duration」
では、Stateが切り替わるタイミングやアニメーション同士のつながり方について詳しく確認していきます。


こちらはUnity初心者向けの記事をテーマ別にまとめています。
▼ Unity初心者向け記事まとめはこちら


こちらのマガジン「ミニゲーム作成講座 全8回セット」でもシーンの切り替えなどを活用して、初心者でも知識ゼロから作れるミニゲーム作成講座を紹介しています。

さらにステップアップの「スマホで遊ぶジャンプゲーム 8回セット」のマガジンもぜひご活用ください。


ファイブボックスでは、スクラッチやUnityの個別指導のオンラインレッスンを行っています。
ご興味のある方は当サイト、オンラインレッスンから、無料体験授業へお問い合わせ下さい。

いいなと思ったら応援しよう!

ファイブボックス よろしければ応援お願いします! いただいたチップはクリエイターとしての活動費に使わせていただきます!