Unity: xボタンだけでダッシュとローリングをできるようにする

Unity入門 - Project Bonfire

今まで手抜きでローリングをダッシュのボタンを分けていましたが、ダークソウルのように、xボタンだけで ダッシュとローリングをできるようにします。動作が怪しげですが、ついでに同じボタンでジャンプもできるようにします。

実装

ボタンを押してすぐ離すとローリング、ボタンを長く押すとダッシュ。ダッシュ中に素早くボタンを押し直すとジャンプします。ジャンプのときもボタンをすぐ離す必要があります。(ダークソウルと動作が異なります)

PlayerCtrl.cs

変数の追加です。コメントに書いてある通りです。

        // xボタンの入力が、ローリングからダッシュになるまでの時間を計算するための変数
        float timeSinceInputFire1 = 0f;

        // isRunning が false になるのを遅延させるために使う変数
        bool isRunningButton = false;
        float timeSinceInputFire1ButtonUp = 0f;

ファイルの末尾のメソッドですが、上記2つのタイマーを進めます。

        //
        // その他のメソッド
        //
        private void UpdateTimer()
        {
            timeSinceInputFire1 += Time.deltaTime;
            timeSinceInputFire1ButtonUp += Time.deltaTime;
        }

本体がここから本体です。

ボタンを押したタイミングで、1つ目のタイマーを開始します。0.3秒以内にボタンが離された場合、条件によって処理を行います。

  1. ダッシュ中ならジャンプ
  2. 実装していませんが、スティックをたおしていなければ、バックステップ
  3. スティックを倒していれば、ローリングをします。

0.3秒以上ボタンが押し続けられていたら、ダッシュの処理を行います。

ボタンが離されたタイミングで、もう1つのタイマーを起動し、ボタンが離されて0.4秒以上経過したらダッシュをやめます。0.4秒以内にもう1度ボタンを短く押されたらジャンプになります。短い時間でなくてもジャンプする方が良ければ else の中に処理を追加してください。(アニメーションもつけていないので面倒なので書きませんでした。)

            // x ボタンで ローリングと加速とジャンプ
            if (Input.GetButtonDown("Fire_1"))
            {
                timeSinceInputFire1 = 0f;
            }
            if (timeSinceInputFire1 < 0.3f)
            {
                if (Input.GetButtonUp("Fire_1"))
                {
                    if (state == State.Walking && status.isGrounded)
                    {
                        if (isRunning)
                        {
                            // ダッシュジャンプ
                            nextState = State.Jump;
                        }
                        else if (Mathf.Approximately(GetMagunitudeStickL(), 0f))
                        {
                            // バックステップ
                            // 未実装
                            Debug.Log("Back Step!");
                        }
                        else
                        {
                            nextState = State.Rolling;
                        }
                    }
                }
            }
            else
            {
                // 加速処理
                if (!Mathf.Approximately(GetMagunitudeStickL(), 0f) && Input.GetButton("Fire_1"))
                {
                    isRunningButton = true;
                    isRunning = true;
                }
                if (isRunning && Input.GetButtonUp("Fire_1"))
                {
                    isRunningButton = false;
                    timeSinceInputFire1ButtonUp = 0f;
                }
            }
            // xボタンを離して、一定時間経過したら 走るのをやめる
            // この一定時間なら x ボタンを離して押し直しても走り続けられる
            if (timeSinceInputFire1ButtonUp > 0.4f && !isRunningButton)
            {
                isRunning = false;
            }

不具合の応急処置

ローリングやジャンプを試しいたら、壁に向かってジャンプすると動けなくなる問題があったので、以下のような応急処置をいれました。

        private void StartJump(State prevState)
        {
            StateStartCommon();
            status.isJumping = true;

            // ダッシュジャンプの速度
            fixedMoveSpeed = GetMagunitudeStickL() * playerMove.walkSpeed * playerMove.runSpeedUpRatio;
            // 崖に引っかかるので動けるようにした
            canRotate = true;
            canMove = true;

            playerMove.AddJumpPower();
        }

バタバタとローリングをやっていると、キャラクターの向きが変わるのが遅すぎて、思った方向にローリングができない場合があるため、回転速度を上げました。操作性を重視するならもう少し速い方がいいかもしれません。ただ、速くしすぎるとアニメーションがぎこちなくなります。

PlayerMove.cs

        // 回転速度
        const float rotationSpeed = 1080.0f;

ファイル

おわりに

次回 IKを使って、両手持ち武器の手の位置を合わせる方法について書きます。