yamada_yoshiki Posted by

おはようございます!こんにちは!こんばんは!おやすみなさい!
山田です。

次回に引き続きUnityを使用してゲームを作っていきたいと思います!!!

今回はMecanimを使用してアニメーションをつけていきます。

Mecanim(メカニム)とは

アニメーションの作成から実行までをUnityで行える機能です。

ゲーム設計時にパラパラアニメを作成して、各アニメーションの切り替えタイミングを指定しておきます。
すると、プレイ時にMecanimオブジェクトの状態を判断し、自動的にアニメーションを切り替えて再生してくれます。

Mecanimを使うには下記の用語を知る必要があります。

スプライト:パラパラアニメに使う為の画像
Animation Clip:スプライトをまとめたファイル
Animator Controller:どのタイミングでAnimation Clipを再生するか指定する
Animatorコンポーネント:Animator Controllerをセットするコンポーネント

Animationウィンドウを開く

ヒエラルキーウィンドウのオブジェクト→Window→Animation→AnimationAnimationウィンドウを開きます。

Animation Clipを作る

Animationウィンドウを開いたら、Create(作成)ボタンをクリックしてください。

クリックするとAnimationファイルを作成することができるので、あらかじめ作成していた走るモーション画像(スプライト)が保存されているファイルをAssetsファイル内に保存しているのでそちらに追加します。

AnimationウィンドウAdd Property→Sprite Renderer→Spriteの+ボタンをクリックしてください

走るモーション画像(スプライト)のファイルをプロジェクトウィンドウから開き、ドラッグ&ドロップAnimationウィンドウに追加していきます。

Animationウィンドウ左上のスタートボタンを押すとゲームウィンドウ内のキャラクターが動くとおもいます。

モーションのループを止めるにはAnimation ClipをクリックしてLoop Time(ループ時間)のチェックを外します。

同様にジャンプと通常時Animation Clip新しいクリップを作成(Create New Clip)をクリックして作成します。

Animator Controllerを作る

走るモーション(player-run)ジャンプモーション(player-jump)が作成できたのでAnimator Controllerを使ってアニメーションの切り替えを行います。

Animator Controllerで設定できるのは下記になります。
・どのAnimation ClipからどのAnimation Clipに遷移するか?
・どのAnimation Clipがどのタイミングで遷移するか?

まずはプロジェクトウィンドウAnimator Controller(オブジェクト名(player-stand-2)のやつ)をダブルクリックし、インスペクターウィンドウ開くボタンをクリックしてAnimationウィンドウを開きます。

Animationウィンドウには作成したAnimation Clipである『player-run(走る)』『player-jump(ジャンプ)』『player-stand(通常)』があります。

他の『Any State』は現在の状態に限らず特定のアニメーションに遷移したい時に使うClipです。
『Entry』アニメーションを開始する時に使います。

最初は作成した走るモーションが呼ばれているのでゲームの開始と同時にキャラクターが走っています。

『Entry』を右クリックし、デフォルトステート(初期状態)『player-stand』に変更します。

更に『player-stand』を右クリックし、Make Transition(遷移先を作成)を選択し画像のように遷移先を指定しますることで、各モーションの遷移が完了です。

遷移のタイミングを設定する(走る→通常)

まずは走るモーションから通常状態に遷移するタイミングを設定します。
『player-run』から『player-stand』に向かっている矢印を選択し、インスペクターウィンドウSettingsを画像のように設定します。

パラメータの意味を下記にまとめています。
Has Exit Time(終了時間あり):アニメーションの再生が終了した時に、自動的に別のアニメーションに遷移するか
Exit Time(終了時間):アニメーションの終了時間を設定(0.0~1.0)
Transition Duration(遷移間隔):次のアニメーションへの遷移時間を設定(0.0~1.0)
Transition Offset(遷移オフセット) :次のアニメーションを再生し始める時間を設定(0.0~1.0)

遷移のタイミングを設定する(通常→走る)

続いて、通常状態から走るモーションに遷移するタイミングの指定をします。
(今回の場合ではBボタンまたはスペースキーが押された時)

Animationウィンドウの左上のParametersタブを開き、その下にある+ボタンをクリックしてTriggerを選択し、作成されたTriggerの名前を『runTrigger』に変更します。

Float:遷移条件に浮動小数点を使う場合
Int:遷移条件に整数を使う場合
Bool:遷移条件に真理値を使う場合
Trigger:遷移条件にトリガーを設置する場合

Triggerを作成できたら『player-stand』から『player-run』に向かう遷移矢印を選択し、インスペクター遷移条件の詳細情報を設定します。

Conditions+ボタンをクリックし、表示されるドロップダウンリストからrunTriggerを選択します。
『player-jump』も同様に設定します。

ソースコードの変更

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

public class player : MonoBehaviour
{
    Rigidbody2D rigid2D;        // 重力オブジェクト
    Animator animator;          // アニメーションオブジェクト
    float jumpForce = 500.0f;   // ジャンプ力
    float walkForce = 30.0f;    // 移動速度
    float maxWalkSpeed = 20.0f; // 最大速度
    bool leftBtn = false;       // 左ボタン押下フラグ
    bool rightBtn = false;      // 右ボタン押下フラグ

    // スタートメソッド
    void Start() {
        // 各メンバ変数の取得
        this.rigid2D = GetComponent();
        this.animator = GetComponent();
    }

    // アップデートメソッド
    void Update() {
        // 左矢印キー・左ボタンが押されている間
        if (Input.GetKey(KeyCode.LeftArrow) || leftBtn) {
            playerMove(-1, "run");
        }

        // 右矢印キーが右ボタン押されている間
        if (Input.GetKey(KeyCode.RightArrow) || rightBtn) {
            playerMove(1, "run");
        }

        // スペースキーが押された時
        if (Input.GetKeyDown(KeyCode.Space)) {
            playerMove(0, "jump");
        }

        // 『B』キーが押された時
        if (Input.GetKeyDown(KeyCode.B)) {
            playerMove(0, "attack");
        }
    }

    // プレイヤの移動
    public void playerMove(int key, string mode) {
        switch(mode) {
            case "run":
                // アニメーション
                this.animator.SetTrigger("runTrigger");
                
                // プレイヤの速度
                float speedx = Mathf.Abs(this.rigid2D.velocity.x);

                // スピード制限
                if(speedx < this.maxWalkSpeed) {
                    this.rigid2D.AddForce(transform.right * key * this.walkForce);
                }

                // 動く方向に反転
                if(key != 0) {
                    transform.localScale = new Vector3(key*7, 5, 5);
                }
            break;
            case "jump":
                // アニメーション
                this.animator.SetTrigger("jumpTrigger");
                // 移動方向
                this.rigid2D.AddForce(transform.up * this.jumpForce);
                break;
            case "attack":
                transform.Translate(0, -1, 0);
                break;
        }
    }

    // 左ボタンが押されている時
    public void LButtonDown() {
        leftBtn = true;
    }
    // 左ボタンが押されていない時
    public void LButtonUp() {
        leftBtn = false;
    }
    // 右ボタンが押されている時
    public void RButtonDown() {
        rightBtn = true;
    }
    // 右ボタンが押されていない時
    public void RButtonUp() {
        rightBtn = false;
    }
    // Aボタンが押された時
    public void AButtonDown() {
        playerMove(0, "jump");
    }
    // Bボタンが押された時
    public void BButtonDown() {
        playerMove(0, "attack");
    }
}

各アニメーションの処理の追加とプレイヤ移動の関数で渡されるmodeにより、全てのモーションを管理するようにしています。

また、入力とアニメーションが遅れたり早かったりする場合はSettingsの設定を変更し、対応してください。

親子関係を持たせる

 

親子関係オブジェクト同士を固定させる時に使います。

今回ではプレイヤーを親メインカメラを子としてプレイヤーが動くとメインカメラも動くようにしています。
(今後ちゃんとした追跡処理を紹介しますがとりあえず)

ヒエラルキーウィンドウメインカメラオブジェクトプレイヤーオブジェクトドラッグ&ドロップしてあげるだけでできます。

最後に

今回はMecanimを使ったアニメーションについて紹介しました。
キャラクターに動きを持たせることでゲームらしくなってきました(笑)

今回のゲームも下記URLから動かすことが可能です。
http://takuan1019.tk/game4/