Unity

【Unity】RobotKyleでいろい~その5~ レーザーソードにアニメーションをつける

投稿日:

概要

前回(RobotKyleでいろい~その4~)ではRobotKyleにレーザーソードを持たせてソードをON/OFFさせるところまで実現しました。

今回はさらにRobotKyleにレーザーソードで攻撃する動作を付け加えていきたいと思います。

完成イメージ


Step1 : 攻撃Animationの調達

Unity Asset Storeにはソード系の攻撃Animationが沢山ありますが、今回はこのAssetを使用させて頂くことにしました。

https://assetstore.unity.com/packages/3d/animations/sword-and-shield-animations-pack-164596#reviews

RobotKyleにシールドは持たせてないですが、斬撃のアニメーションがダイナミックでカッコいいのでこれに決めました。Asset Storeからダウンロードし、PackageManagerからImportします。

Step2 : Animationの設定

Step1でインポートしたSword and Shield PackのFBXフォルダに入っているFBXのうち、Attack01とIdleをCtrl+Dで複製します。

複製されたファイル名はそのままでも構いませんが、後で見つけやすくするためにF2ボタンでSwordAttack、SwordIdleに名前を変更しておきます。

なお、このSword and Shield Packのアニメーションはインポートした時点でデフォルトでRigがHumanoidに設定されていますが、もし他のパッケージの攻撃アニメーションを使用する場合は複製する前にAnimation ClipのRigでAnimation TypeをHumanoidに設定しておいてください。

Step3 : SimpleAnimationへの紐づけ

今回もAnimationの再生はSimpleAnimationを使用してスクリプトで制御していきます。まずはInspectorでSimpleAnimationのスクリプトのSizeを6にした上でSwordAttackとSwordIdleを追加します。アニメーションクリップはStep2で準備したものを指定しておきます。

Step4 : 制御スクリプトの作成

ここでは前々回、前回で作成したキーボード操作による移動とソードON/OFFのスクリプトを統合しつつさらに攻撃アニメーションを制御するスクリプトを作成していきます。

具体的には以下の仕様を満たすコードにします。

  • 攻撃はレーザーソードをONにしてる時だけしか行えない制限をかける
  • レーザーソードをONしているときはSwordIdleでIdleし、OFFしているときは通常のIdleになるようにする
  • 移動中、ダッシュ中、ジャンプ中もソードONできるようにする
  • 移動中、ダッシュ中、ジャンプ中も攻撃できるようにする

次のようなコードになります。

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

public class PlayerCon : MonoBehaviour
{
    // Start is called before the first frame update

    //Status
    [SerializeField] public bool onGround = true; //地面接地フラグ
    [SerializeField] public bool inJumping = false;//ジャンプ中フラグ
    [SerializeField] public bool inAttacking = false;//攻撃中フラグ
    [SerializeField] public bool withSwordsOn = false;//ソードONフラグ
    [SerializeField] public bool toSwordsOn = false;//ソードONにするフラグ
    [SerializeField] public bool inIdle = false;//Idle状態フラグ
    [SerializeField] public bool inRunning = false;//移動中フラグ
    [SerializeField] public bool inRotating = false;//移動中フラグ
    [SerializeField] public bool inSprinting = false;//ダッシュ中フラグ
    [SerializeField] public bool inSwordIdle = false;//ソードONのIdleフラグ
    [SerializeField] public bool inPushedSwordKey = false;//ソード有効化キー押下済みフラグ
    [SerializeField] public bool inPushedAttackKey = false;//ソード有効化キー押下済みフラグ




    //rb Variable
    Rigidbody rb;

    //Run speed
    float speed = 0.06f;

    //Sprint speed
    float sprintspeed = 0.09f;


    //Angle change speed
    float angleSpeed = 2;

    //variable
    float v;
    float h;

    //Defining SimpleAnimation
    SimpleAnimation simpleAnimation;

    //LaserSword
    GameObject laserswordObj;




    void Start()
    {

        //Rigidbodyコンポーネントの取得
        rb = this.GetComponent<Rigidbody>();

        //プレイヤーの回転抑止
        rb.constraints = RigidbodyConstraints.FreezeRotation;

        //シンプルアニメーションコンポーネントの取得
        simpleAnimation = GetComponent<SimpleAnimation>();

        //LaserSwordオブジェクトの取得
        laserswordObj = GameObject.Find("LaserSwordPrefab");
    }

    // Update is called once per frame

    void Update()
    {
        /*
         * フラグ初期化
         */
        inRunning = false;
        inSprinting = false;
        inRotating = false;

        /*
         *基本動作制御部
         */

        //左シフトキーでダッシュスピード、それ以外はふつうのスピードを定義
        if (!inAttacking &amp;&amp; !inJumping)
        {

            if (Input.GetKey(KeyCode.UpArrow) &amp;&amp; Input.GetKey(KeyCode.LeftShift))
            {
                transform.position += transform.forward * sprintspeed;
                inSprinting = true;
            }
            else if (Input.GetKey(KeyCode.DownArrow) &amp;&amp; Input.GetKey(KeyCode.LeftShift))
            {
                transform.position += transform.forward * -sprintspeed / 2;
                inSprinting = true;
            }
            else if (Input.GetKey(KeyCode.UpArrow))
            {
                transform.position += transform.forward * speed;
                inRunning = true;
            }
            else if (Input.GetKey(KeyCode.DownArrow))
            {
                transform.position += transform.forward * -speed / 2;
                inRunning = true;
            }
        }

        //旋回動作
        if (Input.GetKey(KeyCode.RightArrow))
        {
            transform.Rotate(Vector3.up * angleSpeed);
            inRotating = true;
        }
        else if (Input.GetKey(KeyCode.LeftArrow))
        {
            transform.Rotate(Vector3.up * -angleSpeed);
            inRotating = true;
        }

        //ジャンプ動作
        //スペースキーが押されて、地面に設定しているとき
        if (Input.GetKey(KeyCode.Space) &amp;&amp; onGround)
        {
            //速度を一旦0に初期化
            rb.velocity = new Vector3(0, 0, 0);

            //上(ジャンプで上がる方向)に力を発生
            rb.AddForce(transform.up * 600);


            //移動中にジャンプボタンを押した場合は斜めにジャンプさせるため前方方向へもそれぞれ力を発生
            //ダッシュ中とふつうの移動で発生させる力を変える
            if (Input.GetKey(KeyCode.UpArrow) &amp;&amp; Input.GetKey(KeyCode.LeftShift))
            {
                rb.AddForce(transform.forward * 250);
            }
            else if (Input.GetKey(KeyCode.UpArrow))
            {
                rb.AddForce(transform.forward * 180);
            }
            else if (Input.GetKey(KeyCode.DownArrow))
            {
                rb.AddForce(transform.forward * -100);
            }
            //地面接地フラグをfalseに
            onGround = false;

            //ジャンプフラグをtrueに
            inJumping = true;
        }


        if (Input.GetKeyDown(KeyCode.C))
        {
            inPushedSwordKey = true;
        }

        if (Input.GetKeyDown(KeyCode.Z))
        {
            inPushedAttackKey = true;
        }

        /*
         *アニメーション制御部
         */

        //LaserSwordのスクリプト取得
        DigitalRuby.LaserSword.LaserSwordScript laserSwordScript = laserswordObj.GetComponent<DigitalRuby.LaserSword.LaserSwordScript>();

        //攻撃動作の最中(80%完了まで)は攻撃中フラグを保持するようにする
        if (simpleAnimation.GetState("SwordAttack").normalizedTime >= 0.8)
        {
            inAttacking = false;
        }

        //①ここからは前方後方移動中の場合のアニメーションの制御
        //前方後方移動キーが押されたとき
        if (inPushedSwordKey)
        {
            if (!withSwordsOn)//現在ソードOFF状態のとき
            {
                toSwordsOn = true;//ソードONフラグをtrueに
            }
            else if (withSwordsOn)//現在ソードON状態のとき
            {
                toSwordsOn = false;//ソードONフラグをfalseに
            }
        }

        //ソードがONで攻撃ボタンが押されたとき
        if (withSwordsOn &amp;&amp; inPushedAttackKey)
        {
            //攻撃アニメーションを再生
            simpleAnimation.CrossFade("SwordAttack", 0.1f);

            //攻撃キー押下済みフラグをfalseに
            inPushedAttackKey = false;

            //攻撃中フラグをtrueに
            inAttacking = true;
        }
        //移動中フラグもしくはダッシュ中フラグが中のとき
        else if (inRunning || inSprinting)
        {
            //ジャンプ中フラグがtrueのとき
            if (inJumping)
            {
                //ジャンプアニメーションを再生
                simpleAnimation.CrossFade("Jump", 0.1f);

            }
            else if (inAttacking) { }//攻撃中の場合は特に何もせず(攻撃アニメーションを優先)
            else if (inSprinting)
            {
                //スプリントアニメーションを再生
                simpleAnimation.CrossFade("Sprint", 0.1f);
            }
            else//通常移動の場合
            {
                //移動アニメーションを再生
                simpleAnimation.CrossFade("Run", 0.1f);
            }
            
        }
        //ジャンプ中で攻撃中でないとき
        else if (inJumping &amp;&amp; !inAttacking)
        {
            //ジャンプアニメーションを再生
            simpleAnimation.CrossFade("Jump", 0.1f);
        }
        else
        {
            if (inAttacking) { }//攻撃中は攻撃アニメーションを継続
            else if (inJumping) { }//ジャンプ中はジャンプアニメーションを継続
            else if (inPushedSwordKey) { }//ソードON/OFFキー押下中も今のアニメーションを継続
            else//それ以外
            {   
                //ソードをONしているとき
                if (withSwordsOn)
                {
                    //SwordIdlwを再生
                    simpleAnimation.CrossFade("SwordIdle", 0.1f);
                }
                else
                {
                    //ふつうのIdleを再生
                    simpleAnimation.CrossFade("Default", 0.1f);
                }
            }
        }

        /*
         * ここからソードのON/OFF制御
         */
        //ソードON/OFFキーが押下され、攻撃モーション中でない場合
        if (inPushedSwordKey &amp;&amp; !inAttacking)
        {
            //ソードONフラグがtrueなら
            if (toSwordsOn)
            {
                //レーザーソードをAcfivate
                laserSwordScript.Activate();
                //ソードON中フラグをtrueに
                withSwordsOn = true;
                //ソードON/OFFキーフラグをfalseに
                inPushedSwordKey = false;
                //ソードON予定フラグをfalseに
                toSwordsOn = false;
            }
            else//ソードONフラグがfalseなら
            {
                //レーザーソードをDeactivate
                laserSwordScript.Deactivate();
                //ソードON/OFFキーフラグをfalseに
                withSwordsOn = false;
                //ソードON/OFFキーフラグをfalseに
                inPushedSwordKey = false;
            }
        }

    }

    void OnCollisionEnter(Collision col)
    {
        if (col.gameObject.tag == "Ground")
        {
            onGround = true;
            inJumping = false;
            simpleAnimation.Stop("Jump");
        }
    }

上記スクリプトをRobotKyleにアタッチしてGameを実行すると冒頭のgifのような動作ができます。

-Unity

執筆者:


comment

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

関連記事

UnityでNon-convex MeshCollider with non-kinematic Rigidbody is no longer supported since Unity 5.が出た時の対処法

Contents1 概要2 環境3 エラー内容4 対処法15 対処法2 概要 UnityでAsset Storeからフリーの武器をダウンロードして使用していたら、以下のエラーがでたのでその対処方法につ …

【Unity】既存のAnimationをRead-Onlyから編集できるようにする

Contents1 概要2 環境3 Read-Onlyになる事象4 Read-Onlyを回避する方法 概要 Unityで既存のAnimationをキャラクターにAttachする際、Animationで …

【Unity】 Standard Assetsのダウンロードとインポート

Contents1 目的2 環境3 Step1 : Asset Storeを開く4 Step2 : Standard Assetsのインストール5 まとめ 目的 UnityでStandard pack …

【Unity】他オブジェクトのスクリプトのメソッドがどうしても取ってこれない原因と対処法

Contents1 概要2 環境3 まず最初に確認すべきこと4 結論:名前空間を指定していなかった5 エラーの実例5.1 原因6 まとめ 概要 Unityでほかのスクリプトで定義されているObject …

【Unity】ThirdPersonUserControlの方向転換動作おかしい時の対処

Contents1 事象2 調査3 対処 事象 Standard AssetsのThirdPersonUserControlを使用してEthanを動かすとき、デフォルトの正しい動きは↑↓キーで前進後退 …

言語切り替え

カテゴリー