Unity勉強中!あこがれだったプログラマーに今からなろう!

昔あこがれだったプログラマー。今からでもUnityを勉強してみようと思い立ち、チャレンジ開始! Unity勉強メモや、悪戦苦闘な日々の記録です。

α版のデバッグをしよう(バグの原因特定と解決②):3Dアクションゲームを作ろう(21)

前回に引き続き、3Dアクションゲームのα版のバグ取りを行っています。

前回見つけたバグ🪳は以下の通りです。
①回復用の魔法陣が一箇所でしか表示されない。
②一種類の敵の生成が止まってしまう。
③移動床に横から接触すると、移動床に引きずられてしまう。
④地面に沿うようにジャンプすると、ジャンプのままになってしまう。
⑤特定のタイミングで攻撃モーションのままになってしまう。そうなると移動不能状態になる。

この中で①と②は前回解決済みなので、今回は③から虫捕りを始めよう。

「③移動床に横から接触すると、移動床に引きずられてしまう。」
実はこのバグはUnity上のテストプレイでも確認しており、修正を忘れていたバグです。😅

移動床のスクリプトは、れーさんのサイトで説明されていたものを使用しています。

dkrevel.com

2Dゲーム用だけど、3Dでもバッチリ動く。
PlayerControllerのOnCollisionEnterで移動床と接触していると判定し、移動床との場合は移動床の移動速度を
取得してPlayerのRigidbody.Velocityに加算しています。
これにより、移動床に乗っているときは、移動床と同じようにPlayerが移動できますが、
ここまで書いていてわかる様に、移動床を踏まずに横に触れただけでも、移動床の移動速度を取得してしまうので
当然、移動床にPlayerが引きずられてしまう🤣

れーさんのスクリプトでは、Playerの高さと接触したポイントの座標から、移動床を踏んだのか接触したのかを判定
しているので、この問題は起きないようにしっかり対策されています。

そもそも、れーさんのゲームは2Dアクションで、敵を踏んだか敵にぶつかったかの判定も必要なので、この高さ判定の計算が
入っていますが、僕のゲームでは移動床しか判定の必要がありません。
それでもこの計算方法を使ってもいいのですが、どうせなら、もっとシンプルに修正することにしました。

移動床の動きとリンクするだけの一回り大きな床を作理、移動床を覆います。
次に移動床自体はMesh Rendererをoffにして透明に変更。
つまり、移動床に上からし接触できない様にする力技修正ですね🤣

・・・😅
とにかく、これでこの問題も解決。


「④地面に沿うようにジャンプすると、ジャンプのままになってしまう。」
ジャンプアニメーションの遷移は次の様になっています。


ジャンプキーが押されるとjumpフラグがtrueになり、上昇中のアニメに遷移、次にjumpフラグがfalseになれば下降中アニメに遷移します。
下降中アニメの状態(jumpフラグがfalse)で接地すれば着地アニメに遷移する仕組みですね。

肝心のjumpフラグがfalseになるのは、ジャンプキーが押されてから、空中にいる時間が0.3秒経過したタイミングにしていました。

        if(!IsGround)//接地判定がfalse、つまり空中状態。
        {

            flyingtime += Time.deltaTime;
            PlayerAnimator.SetFloat("flyingTime",flyingtime);
            if(flyingtime>0.3f)
            {
                PlayerAnimator.SetBool("jump",false);//空中にいる時間が0.3秒以上ならjumpフラグをfalseに変更。
            }
        }

つまり、ジャンプ時間が0.3秒以内で接地するような状況だと、jumpフラグがfalseでないため着地アニメに遷移できず、
ジャンプのままになるという理屈です。

なので、シンプルにジャンプキーが押されて0.3秒後に強制的にjumpをoffにするように修正しました。

            flyingtime += Time.deltaTime;
            PlayerAnimator.SetFloat("flyingTime",flyingtime);
            if(flyingtime>0.3f)
            {
                PlayerAnimator.SetBool("jump",false);//空中にいる時間が0.3秒以上ならjumpフラグをfalseに変更。
            }

考えすぎて、自分で複雑にしすぎていた様です。😅
これであっさり解決しました。😭

最後は、「⑤特定のタイミングで攻撃モーションのままになってしまう。そうなると移動不能状態になる。」
これが、なかなか出ないバグで、
テストプレイを繰り返しても全く発生してくれません。しかし何かのタイミングで不意にこのバグが発生します。
発生頻度が低すぎて調査ができずにいたのですが、スタジオしまづのメンバーにテストプレイをお願いしたところ、
Playerが攻撃モーション中にモンスターからダメージを受けた時に、このバグが発生する事をKatsumaさんが突き止めてくれました🙇

おかげで、こちらのバグも原因はアニメーション遷移にあるのではないかと仮定できました。

攻撃中に移動できると、攻撃モーションのまま横滑りしてしまうのですが、これが嫌で、
実は攻撃中には移動できないように制限をかける様にしており、これが原因ではないかと思う。
・・・思う。ってのは、これだけが、確証が取れてないからです😅
何せ、ほんとにこのバグ。狙ってもなかなか発生させられません。🤣

攻撃の仕組みはこんな感じです。

    void Attack()
    {
        if(Sta>9)//攻撃に必要なスタミナがあるか判定
        {
            if(inputSystemSC.Player.Fire.triggered)
            {
             IsMoveing=true;        

                if(PlayerAnimator.GetBool("Combo")==true && Sta>9) //コンボ判定2
                {
                    PlayerAnimator.SetBool("Combo2",true);
                }

                if(PlayerAnimator.GetBool("Attack")==true && Sta>9 ) //コンボ判定
                {
                    PlayerAnimator.SetBool("Combo",true);
                }
                else
                {
                    PlayerAnimator.SetBool("Attack",true); //通常攻撃
                    canMove=false; //ここで移動制限
                }
            }
        }
    }

移動制限の解除はアニメーション中のEventで行っています。

攻撃のアニメーションが終了すれば移動制限が解除されるので、問題がない様に見えますが、

被ダメージアニメーションへの遷移がAny Statusからになっているため、
攻撃アニメーションのタイミングによって、移動制限が解除されないパターンがあるのかもしれません。

とりあえず、被ダメージで移動制限や攻撃関係のフラグを全部リセットするように修正してみました。

    public void OnDamage()
    {
        PlayerAnimator.SetBool("Attack",false);
        PlayerAnimator.SetBool("Combo",false);
        PlayerAnimator.SetBool("Combo2",false);
        CanMove();
        if(NoDamage){return;}
        audioSource.PlayOneShot(damageSE);
        PlayerAnimator.SetTrigger("damage");
        HP=HP-20;
    }

このバグだけは、これで解消できたのか不安ですが、
これでパッと確認できたバグは対応できたと思います。

もう少しテストプレイを繰り返して、いよいよ一般公開しようと思います!