Unity

【Unity】入力値によってアニメーション「歩く→走る」に切り替える方法【おまけ:シフト移動の実装も(ブレンドツリー)】

本記事内には、アフィリエイトリンクを含む場合があります

本記事では、
入力値でアニメーションを切り替える方法を紹介します。

それが用いられる一番の例として、
「歩くモーション」から「走るモーション」への遷移を実装していきます。

さらに、後半には、
"前を向いたまま、前後左右に歩く・走る"
という「シフト移動」の実装方法も解説します。

1.3Dモデルとアニメーション(モーション)の用意

まずは、3Dモデル(ヒト型)とアニメーションファイルを調達しましょう。

3Dモデルは自分で用意していただいてもよいですし、
アニメ―ションファイルを調達する際に得られるMixamoのモデルを使ってもよいです。

3Dモデルを自分で用意する方は、図のようにシーンを配置します。
私は"SuperInamo"を使用します。
※これは顔面を自分の顔写真に置き換えたモデル(笑)作り方はこちら↓

3DモデルのRigについて、Animation TypeをHumanoidにしてApplyします。

その後、Hierarchにドラッグ&ドロップして、シーンに配置します。
また、Planeを追加して、白くて大きな地面も作成します。

次に、右クリックからAnimation Controllerを作成し(SuperInamoAniConと名付けた)、シーンに配置した3DモデルのAnimatorコンポーネントに紐づけます。

なお、後々アニメ―ションを再生するのに、
アニメーションがもつ動きで座標が変わると面倒なので
Apply Root Motionのチェックを外し、無効にしておきます。

Unityでは、GameやHierarchyなどは、図のように配置すると作業しやすい↓

ここでAnimatorウィンドウがUnity Editorにない方は、WindowタブからAnimationのAnimatorをクリックして配置させておいてください。

 

次にアニメーションファイルを、Mixamoから調達します。

必要なアニメーションは、Idle、Walking、Runningといったモノです(こまかな種類は任意で)。

なお、後々、シフト移動のアニメーションまで実装したい方は、
下図のようにLocomotion PackとRunning Backward、Walking、Walking Backwardのアニメーションをダウンロードしておいてください。

このとき、Mixamoのプレビューで動いている3Dモデルも
ダウンロードすることをオススメします(Tposeを選べばOK)。

アニメーションファイルをAssetsフォルダ内にAnimationsフォルダを作成し、その配下にドラッグ&ドロップでインポートします。

Locomotion Packをダウンロードしたなら、Mixamoの3Dモデルも付属されているはずなので、まずはそいつのRigから「Humanoid」にしてApplyします。

その後、全アニメーションファイルを選択し、Rigを「Humanoid」、Avatar Definitionを「Copy From Other Avatar」にして、SourceをMixamoモデルのAvatarに選択します。

こうする理由が気になる方は、MixamoアニメーションがUnityで動かない?足がおかしくなる?時の対処法【アバターの適用が重要】を参照ください。

各アニメーションファイルのAnimationタブにて、IdleやWalking、RunningはLoop Timeにチェックを入れます(繰り返す動きなので)。

また、Locomotion Packの各アニメーションは、表示名がMixamo~になっていてわかりづらいので、Idleなど名前をつけることをオススメします。

シーンの3Dモデルを選択すると、SuperInamoAniConの内容がAnimatorウィンドウに表示されます。

そこにIdleのアニメーションファイルをドラッグ&ドロップします。自動でEntlyから繋がり、Default stateとなるはずです。

2.「歩く→走る」への切り替え

同様に、WalkingやRunningのアニメーションファイルもドラッグ&ドロップしていきます。

それらをIdleを右クリックして「Make Transition」でつないでいきます。逆方向にも遷移するようにつなぎます。

その後、左のParamaterの「+」からBoolをクリックし、walking、runningを作成します。

遷移の矢印をクリックし、Conditionsを編集していきます。
Idle→Walkingは、walking:true
Walking→Idleは、walking:false
Walking→Runningは、running:true
Running→Walkingは、running:false

また、それら全てのHas Exit Timeを無効にして、
Conditionsが満たされ次第、アニメーションの途中でも遷移するようにします。

ここでゲームを実行してみましょう。
Aimatorウィンドウのwalkingやrunningにチェックを入れて、モーションが変化するかを確認できます。

これで、Idle→歩く→走ると遷移するAnimatorの準備はできました。

これをスクリプトにて、移動の入力値が一定を越えたり、あるボタンを押しているときだけ、移動が走るに変わったりするようにすれば、OKです。

移動の入力値が一定を越えたら、歩きが走りに変わるスクリプトに関しては、
3-1の末尾に掲載しているスクリプトを参考ください。

 

3.【おまけ】シフト移動の実装

本記事では、おまけにシフト移動も解説します!(おまけというか、これがメイン^^)

シフト移動とは、前を向いたまま(敵に背を向けず)移動することです。

シフト移動は、
FPSのようなシューティングゲームのキャラクターに用いられることが多く、
一方でサードパーソンキャラクターは、
移動する方向を向く(向いた方向にしか移動できない)のがデフォルトになってます。

ですが、メタルギアのように、シューティング時だけ自動でシフト移動できるようにしてたりしますよね。

シューティングでないアクションゲームであっても、
シフト移動モードを実装することは、そのゲームのクオリティ、満足度を上げることにつながります。

しかし、その実装には、キャラクターを操作するプログラムはもちろん、
Animatorにおいても、ひと工夫必要となります。

それを紹介していきます。

3-1.Blend Treeによるアニメーション分岐

どんな、ひと工夫なのかというと、
"前を向いたまま横に歩く"
"前を向いたまま後ろに歩く"
といったアニメーションへの分岐を実装します。

それらの分岐は、前後の移動入力と左右の移動入力が混在した中で行われなくてはいけません。
そのような複雑な場合、Blend Treeという機能を用います。

 

それではBlend Treeを使ってみましょう。
Animatorの、適当なところで、右クリックからCreate Stateの「From New Blend Tree」をクリックします。
すると、Blend TreeというStateが出現します。
これを右クリックし、「Set as Layer Default State」をクリックします。

次に、Parametersの「+」でFloatを追加し、HorizontalとVerticalと名付けます。

Blend TreeをダブルクリックするとBase Layer>Blend Treeへ移動します。
そのBlend Treeをクリックし、そのInspectorを編集していきます。

Blend Typeを「2D Simple Directional」を選択、ParamatersをHorizontal、Verticalにします。

その後、Motionの「+」より項目を設定していきます。

Blend Treeに、Idleおよび前後左右のアニメーションと値を設定したら、
ゲームを実行して、左のHorizontalやVerticalに適当に数値を入力してみましょう。

すごくゆっくりですが、アニメーションが数値によって変化するはずです。

 

次に、この柔軟にアニメーションが変化するBlend Treeの走るバージョンを作成しましょう。

今作ったBlend TreeをShift +Dで複製します。
各Blend Treeの名前をInspectorより変更します(Walk Blend TreeとRun Blend Treeに)。

 

また、Walk Blend TreeとRun Blend Treeの間を右クリックのMake Transitionで両方向から繋ぎます。
各矢印にて、Conditionsでrunningをtrue、falseに設定します。

なお、Walk Blend TreeのSpeedを2に、Run Blend TreeのSpeedは1に設定するのがオススメです。

Run Blend Treeをダブルクリックして、
そのInspectorで設定されているIdle以外のアニメーションを
Run系の前後左右のアニメーションに変更します。

これでゲームを実行してみて、HorizontalやVerticalに適当な数値を入力し、なおかるrunningにチェックを入れると、走るアニメーションに切り替わることを確認できます。

これでBlend Treeに関する基本設定は完了しました。

これらが自動で行われるように、実戦的な設定をしていきましょう。

 

ここでは、Joystickを使います!
理由は、通常のキーボードによる入力では、移動数値が1か0か(キーが押されたか否か)の違いしかないため、歩きと走りに区別ができません。
Joystickなら、ちょっとだけスティックを倒して、0.4といった調整の効く入力ができるからです。

この辺の実装は、スマホゲーム、ゲームコントローラーのスティック入力に通ずるので、知っておいて損はないはず!

では、まずはブラウザでAsset Storeにアクセスし、Joystick Packを入手しましょう。

入手したら、EditorのWindowタブからPackage Manager、My Assetsに切り替えて、検索からJoystick Packを探します。

そしてインポート!

ここから、ゲーム実行時はGameシーンから操作して、挙動をみていくので、カメラなどを整えます。

Main CameraのPosition Y:1 Z:-2、SuperInamoのRotation Y:180にします。

ジョイスティックというUIを実装する前に、Canvasを追加しておく必要があります。
Joystick PackのPrefabから、Fixed Joystickをシーンの左上あたり配置します。
そのままでは大きすぎるので、ScaleをX,Y:0.3にします。

ここから、C#スクリプトによって、

●ジョイスティックで移動の数値を入力する機能、
●一定の数値を越えたら、runnigをtrueとし、歩きから走るアニメーションへのBlend Treeに遷移する機能

を実装していきます。

スクリプト以下の通り↓

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

public class CharaCon : MonoBehaviour
{
    [SerializeField] Joystick joystick;
    Animator anim;

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

    // Update is called once per frame
    void Update()
    {
        float v = joystick.Vertical;
        float h = joystick.Horizontal;

        anim.SetFloat("Horizontal", joystick.Horizontal);
        anim.SetFloat("Vertical", joystick.Vertical);

        if(Mathf.Abs(joystick.Horizontal)>0.9f || Mathf.Abs(joystick.Vertical)>0.9f)
        {
            anim.SetBool("running",true);
        }       
        else
        {
            anim.SetBool("running",false);
        }       
    }
}

3Dモデル"SuperInamo"にこのスクリプトをアタッチ。
FixedJoystickも紐づけします。

Update関数でジョイスティックの縦横の入力値を取得し、その数値をAnimatorのParameterに渡します。

また、Animatorのrunningというboolを0.9以上の数値でtrue、それ以下でfalseになるようにしています。

では、ゲームを実行させてみましょう。
ジョイスティックを操作して、キャラクターが歩いたり、走ったりするアニメーションが作動すればOKです!

 

3-2.キャラクターを移動させる

アニメーションはできました!
次にキャラクターを移動させてみましょう。
移動させると、よりBlend Treeによるシフト移動の効果を体感できます。
(普通の移動とはちがう!)

まず、3DモデルのSuperInamoにRigidbody、Capsule Colliderをアタッチします。

そして、CharaConスクリプトを以下のように修正します。

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

public class CharaCon : MonoBehaviour
{
    [SerializeField] Joystick joystick;
    Animator anim;
    Rigidbody rb;
    Vector3 velocity = Vector3.zero;
    float speed = 0.5f;

    // Start is called before the first frame update
    void Start()
    {
        anim = GetComponent<Animator>();
        //動かす用
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        float v = joystick.Vertical;
        float h = joystick.Horizontal;

        //動かす用
        Vector3 forward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized;   
        Vector3 right = Camera.main.transform.right;

        velocity = new Vector3(speed * h,0,speed * v);
         
        anim.SetFloat("Horizontal", joystick.Horizontal);
        anim.SetFloat("Vertical", joystick.Vertical);

        if(Mathf.Abs(joystick.Horizontal)>0.9f || Mathf.Abs(joystick.Vertical)>0.9f)
        {
            speed = 2f;//動かす用
            anim.SetBool("running",true);
        }       
        else
        {
            speed = 0.5f;//動かす用
            anim.SetBool("running",false);
        }       
    }
    void FixedUpdate()
    {

        //動かす用
        if(velocity!= Vector3.zero) //velocityに入力値があれば
        {
            Vector3 _velocity = Vector3.ClampMagnitude(velocity, 3.6f);
            rb.MovePosition(rb.position + _velocity * Time.fixedDeltaTime);
        }
    }
}

移動は、superInamoがもつRigidbodyのMovePositionを使います。
そして、常にキャラクターが背中にもつカメラを起点に、前後左右を決めています。

これによって、シフト移動(ターゲットを見失いにくい)が実装できるわけです。

ゲームを実行してみましょう。

より、歩く→走る、Blend Treeによって、キャラクターにより生命力を与えられましたね!

ここから、
タッチパネルなどによるカメラ制御を加えれば、FPSゲームっぽくなり、
シフトモードのオン・オフを実装すると、
本格的なサードパーソンゲームにしていくことができるでしょう。

その実装については、また後日紹介するので、
本ページをお気に入り追加して、待っといてくださいな!^^

ABOUT ME
いなも@システマライフハッカー
”仙豆”を開発することを夢見て、健康食品会社で働いていたものの、2016年に出会ったロシアの武術”システマ”こそ、その糸口があると感銘し、勝手にシステマ普及活動を始める。 一方で、クリエイティブなモノ作りが好きで、DX社会で楽しみを見出せる"Unity”を活かして、”スマートかつ快適な暮らし”のヒントを発信している。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA