【Unity】キャラクター操作その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>();

        //&#12503;&#12524;&#12452;&#12516;&#12540;&#12398;&#22238;&#36578;&#25233;&#27490;
        rb.constraints = RigidbodyConstraints.FreezeRotation;

        //&#12471;&#12531;&#12503;&#12523;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12467;&#12531;&#12509;&#12540;&#12493;&#12531;&#12488;&#12398;&#21462;&#24471;
        simpleAnimation = GetComponent<SimpleAnimation>();

        //LaserSword&#12458;&#12502;&#12472;&#12455;&#12463;&#12488;&#12398;&#21462;&#24471;
        laserswordObj = GameObject.Find("LaserSwordPrefab");
    }

    // Update is called once per frame

    void Update()
    {
        /*
         * &#12501;&#12521;&#12464;&#21021;&#26399;&#21270;
         */
        inRunning = false;
        inSprinting = false;
        inRotating = false;

        /*
         *&#22522;&#26412;&#21205;&#20316;&#21046;&#24481;&#37096;
         */

        //&#24038;&#12471;&#12501;&#12488;&#12461;&#12540;&#12391;&#12480;&#12483;&#12471;&#12517;&#12473;&#12500;&#12540;&#12489;&#12289;&#12381;&#12428;&#20197;&#22806;&#12399;&#12405;&#12388;&#12358;&#12398;&#12473;&#12500;&#12540;&#12489;&#12434;&#23450;&#32681;
        if (!inAttacking && !inJumping)
        {

            if (Input.GetKey(KeyCode.UpArrow) && Input.GetKey(KeyCode.LeftShift))
            {
                transform.position += transform.forward * sprintspeed;
                inSprinting = true;
            }
            else if (Input.GetKey(KeyCode.DownArrow) && 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;
            }
        }

        //&#26059;&#22238;&#21205;&#20316;
        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;
        }

        //&#12472;&#12515;&#12531;&#12503;&#21205;&#20316;
        //&#12473;&#12506;&#12540;&#12473;&#12461;&#12540;&#12364;&#25276;&#12373;&#12428;&#12390;&#12289;&#22320;&#38754;&#12395;&#35373;&#23450;&#12375;&#12390;&#12356;&#12427;&#12392;&#12365;
        if (Input.GetKey(KeyCode.Space) && onGround)
        {
            //&#36895;&#24230;&#12434;&#19968;&#26086;0&#12395;&#21021;&#26399;&#21270;
            rb.velocity = new Vector3(0, 0, 0);

            //&#19978;&#65288;&#12472;&#12515;&#12531;&#12503;&#12391;&#19978;&#12364;&#12427;&#26041;&#21521;&#65289;&#12395;&#21147;&#12434;&#30330;&#29983;
            rb.AddForce(transform.up * 600);


            //&#31227;&#21205;&#20013;&#12395;&#12472;&#12515;&#12531;&#12503;&#12508;&#12479;&#12531;&#12434;&#25276;&#12375;&#12383;&#22580;&#21512;&#12399;&#26012;&#12417;&#12395;&#12472;&#12515;&#12531;&#12503;&#12373;&#12379;&#12427;&#12383;&#12417;&#21069;&#26041;&#26041;&#21521;&#12408;&#12418;&#12381;&#12428;&#12382;&#12428;&#21147;&#12434;&#30330;&#29983;
            //&#12480;&#12483;&#12471;&#12517;&#20013;&#12392;&#12405;&#12388;&#12358;&#12398;&#31227;&#21205;&#12391;&#30330;&#29983;&#12373;&#12379;&#12427;&#21147;&#12434;&#22793;&#12360;&#12427;
            if (Input.GetKey(KeyCode.UpArrow) && 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);
            }
            //&#22320;&#38754;&#25509;&#22320;&#12501;&#12521;&#12464;&#12434;false&#12395;
            onGround = false;

            //&#12472;&#12515;&#12531;&#12503;&#12501;&#12521;&#12464;&#12434;true&#12395;
            inJumping = true;
        }


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

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

        /*
         *&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#21046;&#24481;&#37096;
         */

        //LaserSword&#12398;&#12473;&#12463;&#12522;&#12503;&#12488;&#21462;&#24471;
        DigitalRuby.LaserSword.LaserSwordScript laserSwordScript = laserswordObj.GetComponent<DigitalRuby.LaserSword.LaserSwordScript>();

        //&#25915;&#25731;&#21205;&#20316;&#12398;&#26368;&#20013;&#65288;80%&#23436;&#20102;&#12414;&#12391;&#65289;&#12399;&#25915;&#25731;&#20013;&#12501;&#12521;&#12464;&#12434;&#20445;&#25345;&#12377;&#12427;&#12424;&#12358;&#12395;&#12377;&#12427;
        if (simpleAnimation.GetState("SwordAttack").normalizedTime >= 0.8)
        {
            inAttacking = false;
        }

        //&#9312;&#12371;&#12371;&#12363;&#12425;&#12399;&#21069;&#26041;&#24460;&#26041;&#31227;&#21205;&#20013;&#12398;&#22580;&#21512;&#12398;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12398;&#21046;&#24481;
        //&#21069;&#26041;&#24460;&#26041;&#31227;&#21205;&#12461;&#12540;&#12364;&#25276;&#12373;&#12428;&#12383;&#12392;&#12365;
        if (inPushedSwordKey)
        {
            if (!withSwordsOn)//&#29694;&#22312;&#12477;&#12540;&#12489;OFF&#29366;&#24907;&#12398;&#12392;&#12365;
            {
                toSwordsOn = true;//&#12477;&#12540;&#12489;ON&#12501;&#12521;&#12464;&#12434;true&#12395;
            }
            else if (withSwordsOn)//&#29694;&#22312;&#12477;&#12540;&#12489;ON&#29366;&#24907;&#12398;&#12392;&#12365;
            {
                toSwordsOn = false;//&#12477;&#12540;&#12489;ON&#12501;&#12521;&#12464;&#12434;false&#12395;
            }
        }

        //&#12477;&#12540;&#12489;&#12364;ON&#12391;&#25915;&#25731;&#12508;&#12479;&#12531;&#12364;&#25276;&#12373;&#12428;&#12383;&#12392;&#12365;
        if (withSwordsOn && inPushedAttackKey)
        {
            //&#25915;&#25731;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12434;&#20877;&#29983;
            simpleAnimation.CrossFade("SwordAttack", 0.1f);

            //&#25915;&#25731;&#12461;&#12540;&#25276;&#19979;&#28168;&#12415;&#12501;&#12521;&#12464;&#12434;false&#12395;
            inPushedAttackKey = false;

            //&#25915;&#25731;&#20013;&#12501;&#12521;&#12464;&#12434;true&#12395;
            inAttacking = true;
        }
        //&#31227;&#21205;&#20013;&#12501;&#12521;&#12464;&#12418;&#12375;&#12367;&#12399;&#12480;&#12483;&#12471;&#12517;&#20013;&#12501;&#12521;&#12464;&#12364;&#20013;&#12398;&#12392;&#12365;
        else if (inRunning || inSprinting)
        {
            //&#12472;&#12515;&#12531;&#12503;&#20013;&#12501;&#12521;&#12464;&#12364;true&#12398;&#12392;&#12365;
            if (inJumping)
            {
                //&#12472;&#12515;&#12531;&#12503;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12434;&#20877;&#29983;
                simpleAnimation.CrossFade("Jump", 0.1f);

            }
            else if (inAttacking) { }//&#25915;&#25731;&#20013;&#12398;&#22580;&#21512;&#12399;&#29305;&#12395;&#20309;&#12418;&#12379;&#12378;(&#25915;&#25731;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12434;&#20778;&#20808;)
            else if (inSprinting)
            {
                //&#12473;&#12503;&#12522;&#12531;&#12488;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12434;&#20877;&#29983;
                simpleAnimation.CrossFade("Sprint", 0.1f);
            }
            else//&#36890;&#24120;&#31227;&#21205;&#12398;&#22580;&#21512;
            {
                //&#31227;&#21205;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12434;&#20877;&#29983;
                simpleAnimation.CrossFade("Run", 0.1f);
            }
            
        }
        //&#12472;&#12515;&#12531;&#12503;&#20013;&#12391;&#25915;&#25731;&#20013;&#12391;&#12394;&#12356;&#12392;&#12365;
        else if (inJumping && !inAttacking)
        {
            //&#12472;&#12515;&#12531;&#12503;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12434;&#20877;&#29983;
            simpleAnimation.CrossFade("Jump", 0.1f);
        }
        else
        {
            if (inAttacking) { }//&#25915;&#25731;&#20013;&#12399;&#25915;&#25731;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12434;&#32153;&#32154;
            else if (inJumping) { }//&#12472;&#12515;&#12531;&#12503;&#20013;&#12399;&#12472;&#12515;&#12531;&#12503;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12434;&#32153;&#32154;
            else if (inPushedSwordKey) { }//&#12477;&#12540;&#12489;ON/OFF&#12461;&#12540;&#25276;&#19979;&#20013;&#12418;&#20170;&#12398;&#12450;&#12491;&#12513;&#12540;&#12471;&#12519;&#12531;&#12434;&#32153;&#32154;
            else//&#12381;&#12428;&#20197;&#22806;
            {   
                //&#12477;&#12540;&#12489;&#12434;ON&#12375;&#12390;&#12356;&#12427;&#12392;&#12365;
                if (withSwordsOn)
                {
                    //SwordIdlw&#12434;&#20877;&#29983;
                    simpleAnimation.CrossFade("SwordIdle", 0.1f);
                }
                else
                {
                    //&#12405;&#12388;&#12358;&#12398;Idle&#12434;&#20877;&#29983;
                    simpleAnimation.CrossFade("Default", 0.1f);
                }
            }
        }

        /*
         * &#12371;&#12371;&#12363;&#12425;&#12477;&#12540;&#12489;&#12398;ON/OFF&#21046;&#24481;
         */
        //&#12477;&#12540;&#12489;ON/OFF&#12461;&#12540;&#12364;&#25276;&#19979;&#12373;&#12428;&#12289;&#25915;&#25731;&#12514;&#12540;&#12471;&#12519;&#12531;&#20013;&#12391;&#12394;&#12356;&#22580;&#21512;
        if (inPushedSwordKey && !inAttacking)
        {
            //&#12477;&#12540;&#12489;ON&#12501;&#12521;&#12464;&#12364;true&#12394;&#12425;
            if (toSwordsOn)
            {
                //&#12524;&#12540;&#12470;&#12540;&#12477;&#12540;&#12489;&#12434;Acfivate
                laserSwordScript.Activate();
                //&#12477;&#12540;&#12489;ON&#20013;&#12501;&#12521;&#12464;&#12434;true&#12395;
                withSwordsOn = true;
                //&#12477;&#12540;&#12489;ON/OFF&#12461;&#12540;&#12501;&#12521;&#12464;&#12434;false&#12395;
                inPushedSwordKey = false;
                //&#12477;&#12540;&#12489;ON&#20104;&#23450;&#12501;&#12521;&#12464;&#12434;false&#12395;
                toSwordsOn = false;
            }
            else//&#12477;&#12540;&#12489;ON&#12501;&#12521;&#12464;&#12364;false&#12394;&#12425;
            {
                //&#12524;&#12540;&#12470;&#12540;&#12477;&#12540;&#12489;&#12434;Deactivate
                laserSwordScript.Deactivate();
                //&#12477;&#12540;&#12489;ON/OFF&#12461;&#12540;&#12501;&#12521;&#12464;&#12434;false&#12395;
                withSwordsOn = false;
                //&#12477;&#12540;&#12489;ON/OFF&#12461;&#12540;&#12501;&#12521;&#12464;&#12434;false&#12395;
                inPushedSwordKey = false;
            }
        }

    }

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

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

以上

Unityを一から学ぶのにおすすめの本はコチラ

おすすめ

コメントを残す

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