【Unity2D】スクリプトで上下左右アニメ切り替えを行う

Unity2D

Unity2D ARPG

こんにちは。なおキーヌです。

ブログ毎日更新は314日目になります。

前回「スクリプトによるアニメーション遷移の制御」にてスクリプトでアニメーション遷移を行う方法を学びました。

上下左右に対応したアニメーションに切り替えるようにしてみましょう。

主に条件式が重要になってきます。

今回の目的はスクリプトによってアニメーションの変更です。

Unity2DでARPG作成、第7回目始めましょう。

  1. 上下左右のアニメーションファイルを用意しよう
  2. アニメーターに登録して遷移条件を作ろう
  3. スクリプトでキーを押している時だけアニメーションを動かす

上下左右のアニメーションファイルを用意しよう

ドット絵は各自ご用意ください。

まずはアニメーションファイルを作ってお好みのアニメーションを作りましょう。

今回は上下左右のキーに対応するアニメーション切り替えを実装していくので、
ドット絵がない人は適当に画像を用意して上下左右が分かるような画像を用意してください。

プロジェクトからアニメーションファイルを作成、上下左右の歩行アニメーションを作ります。

これは移動時のアニメーターコントローラーを設定しよう:準備編にてやったと思うので、手順は省略します。

アニメーションの作り方を軽く説明しておくと

  • アニメーションファイルを作る
  • アニメーターにD&Dで登録する
  • プレイヤーオブジェクトを選択する
  • アニメーションリストを選択する
  • スプライトリストをD&Dでタイムラインに登録していく

こんな感じですね。

言い忘れてましたが、「立ち状態」のアニメーションも作っておきましょう。

直立不動のドット絵1枚だけでアニメしてませんがアニメーションファイルです(笑)

アニメーターに登録して遷移条件を作ろう

アニメーションが作り終わったら遷移の矢印を作り、矢印を選択して条件式を適用しましょう。

前回で変数は作っていると思いますが、一応左上の+ボタンを押すと変数を作ることが出来ます。

遷移矢印を選択して条件式を設定していきます。

デフォルトトランジションを立ち状態のアニメーションに指定しておき、
上下左右のアニメーションは1~4の状態の時にそれぞれ移行するという仕組みにしましょう。

遷移は以下の画像のようになっていればOKです。

Unity アニメーター

スクリプトでキーを押している時だけアニメーションを動かす

次に上下左右のキーを押している時はそれぞれのアニメーションを離されるまでループする。

そして上下左右どれも押されていなければスタンド状態に戻す。

というスクリプトを組みます。

一旦今回までの完全版スクリプトを載せておきます。

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class Controller : MonoBehaviour
{

    Animator animator;

    int nowAnim = 0;
    float vx = 0;
    float vy = 0;



    public float speed = 30;

    // キー入力順番配列
    // private List<KeyCode> PushedKeyList = new List<KeyCode>();
    private List<KeyCode> PushedArrowKeyList = new List<KeyCode>();

    // Start is called before the first frame update
    void Start()
    {
        animator = GetComponent<Animator>();        
    }

    // Update is called once per frame
    void Update()
    {
        // 毎フレーム数値を初期化
        vx = 0;
        vy = 0;


        // キャラクター移動
        CharaMove();
    }


    // キーのリスト入れ替え関数
    private void KeyAddRemove(KeyCode keycode) {
        if (Input.GetKey(keycode)) {
            // Linqの機能:リストに指定物が中身になければリストに加える
            if (!(PushedArrowKeyList.Contains(keycode))) {
                // あれば削除
                PushedArrowKeyList.Add(keycode);
            }
        } else {
            // Linqの機能:リストに指定物が中身にあればリストにから外す
            if (PushedArrowKeyList.Contains(keycode)) {
                // あれば削除
                PushedArrowKeyList.Remove(keycode);
            }
        }
    }

    // キーチェック関数
    private void KeyCheck() {
        KeyAddRemove(KeyCode.LeftArrow);
        KeyAddRemove(KeyCode.RightArrow);
        KeyAddRemove(KeyCode.UpArrow);
        KeyAddRemove(KeyCode.DownArrow);
    }

    // キャラクター移動
    private void CharaMove() {

        // キーチェック
        KeyCheck();

        // プレイヤーの移動
        PlayerMove();
    }

    private void PlayerMove() {

        if (nowAnim != 10) {

            // まず一番最初に押された
            if (PushedArrowKeyList.Count > 0) {
                if (PushedArrowKeyList[0] == KeyCode.LeftArrow) {
                    vx = -speed;
                    WalkSwitch("LeftWalk");
                    // walkAnimation = "LeftWalk@Player";
                    if (PushedArrowKeyList.Count > 1) {
                        if (PushedArrowKeyList[1] == KeyCode.UpArrow) vy = speed;
                        if (PushedArrowKeyList[1] == KeyCode.DownArrow) vy = -speed;
                    }
                } else if (PushedArrowKeyList[0] == KeyCode.RightArrow) {
                    vx = speed;
                    WalkSwitch("RightWalk");
                    // walkAnimation = "RightWalk@Player";
                    if (PushedArrowKeyList.Count > 1) {
                        if (PushedArrowKeyList[1] == KeyCode.UpArrow) vy = speed;
                        if (PushedArrowKeyList[1] == KeyCode.DownArrow) vy = -speed;
                    }
                } else if (PushedArrowKeyList[0] == KeyCode.UpArrow) {
                    vy = speed;
                    WalkSwitch("UpWalk");
                    // walkAnimation = "UpWalk@Player";
                    if (PushedArrowKeyList.Count > 1) {
                        if (PushedArrowKeyList[1] == KeyCode.LeftArrow) vx = -speed;
                        if (PushedArrowKeyList[1] == KeyCode.RightArrow) vx = speed;
                    }
                } else if (PushedArrowKeyList[0] == KeyCode.DownArrow) {
                    vy = -speed;
                    WalkSwitch("DownWalk");
                    // walkAnimation = "DownWalk@Player";
                    if (PushedArrowKeyList.Count > 1) {
                        if (PushedArrowKeyList[1] == KeyCode.LeftArrow) vx = -speed;
                        if (PushedArrowKeyList[1] == KeyCode.RightArrow) vx = speed;
                    }
                }
            } else {
                WalkSwitch("Stand");
            }
        }
        // 実際の移動
        this.transform.Translate(vx/50, vy/50, 0);        
    }

    private void WalkSwitch(string str) {

        switch (str) {
            case "LeftWalk" :
                nowAnim = 2;
                break;
            case "RightWalk" :
                nowAnim = 4;
                break;
            case "UpWalk" :
                nowAnim = 3;
                break;
            case "DownWalk" :
                nowAnim = 1;
                break;
            case "Stand" :
                nowAnim = 0;
                break;
            default:
                nowAnim = 0;
                break;
        }
        animator.SetInteger("nowWalk",nowAnim);
    }
}

増えている関数は

  • WalkSwitch

になります。

PlayerMove関数側で呼び出しているのを見てください。

それぞれの分岐のところで街頭の文字列を渡していると思います。

その文字列に対してアニメーターのnowWalkを変更していますね。

何もしないと変数を0にしてスタンド状態に戻します。

これで一回実行してみましょう。

Unity アニメーション

……どうでしょうか?

一応上下左右にアニメーションは切り替わっていますね。

しかしアニメが何回も最初から実行されてしまっています。

これはアニメーターでアニメーションの設定を少し弄らないといけません。

次回は押している間はアニメーションをちゃんと再生するようにしてみましょう。

それでは。