たとえばこんなデバッグ方法。
どうも、U.G.M.です。
今日はTPOに合わせたデバッグ方法などをつらつらと書いてゆこうと思います。
デバッグとは?
まず「デバッグ」の定義をしておきましょう。
「意図していない動作を、意図した動作に修正すること」と、デバッグを仮定義します。
はい、ここではGoat Simulatorなどの「バグが楽しい!」「俺が仕様と言ったら仕様」的な言説には消えていただきます。(ボタンを押してGoat Simulatorさんの立っている床を消して、落とす。仕様です) もちろん、これもデバッグっちゃあデバッグなんですが。
閑話休題。
純粋なバグの要件として「入力に対して出力(主に表示)がおかしい」が存在します。
架空のゲームのバグ話、まずは「動いてほしい方向に動かない」というバグがあります。上下が反対とかですね。これは純粋且つ単純なので、すぐわかるでしょう。対策は「入力判定の上下が逆になっているので、上を押したら上に動き、下を押したら下に動く」ように修正します。これがデバッグです。
実践・これがデバッグの本番だ!
ところで、世の中には「床の上で前後の方向ボタンを押したら、最初に押した方向にしか動かなくなり、曲がることも止まることもできない」というバグがあります。今回俺がやらかしたバグです。
もちろん入力周りの問題なので、先頭から追っていけばいずれ解決するのかもしれませんが、今回は「入力と、それに関連する変数・出力結果を画面に表示する」ことでバグを明らかにします。昔「アズールレーン」でデバッグ情報が出せる裏ワザがあった覚えがありますが(むしろ当時、今でもやるんだね、と感心した)、それです。
今回はUnityのCanvas面はいくつでも作れるという特徴を余すところ無く利用して「デバッグ情報だけが出せるテキストメインのuGUI画面(Canvasツリー)を作る」ことにしました。その名もDebugStation!(わかる人だけわかればいい)
この手の画面オーバーレイ、Unityに限らず作り手の誰もが考えて思い思いの実装をしていると思いますが、今回はリアルタイムアクションということで動画に落としてコマで見るためにフレーム数は必須だよね、ということで内部で使っている「count(1フレーム進むたびに1加算)」という変数を利用しています。
でもわかんない!デバッグの深みに迫る!
順調に開発を進めている時に、突然謎の挙動が入る瞬間があります。具体的に言うと(というか、そのために仕込んだわけではないのですが)、ステージクリア時に自機がどこかに移動してしまっているようです。むむむ……?
こういう時に役に立つのは、やはり「状況をテキストファイルに1フレームづつ書き出して、どこがバグフレームなのかを絞ってゆく」作業でしょう。
ご安心を。もちろんそのためのクラスも作ってあります、っていうかそちらの方が先に作ってあって、今回も登場してもらいました「FileOutput.cs」です。(詳しい人は「同じことは標準のDebug.Logでもできるのでは?」と思うかもしれませんが、そちらは1フレーム・1バグに対しての余計な情報量が多すぎるのです)
というわけで、ドン!
ここで判明するのは「ゲームクリアフラグが立った頃合いで、不自然な値がthis.transform.positionに放り込まれている」謎です。これ、どこかのparampos(キャラクタ毎に使い方が違う固有変数として利用)をコピーしちゃってるのかな……。
……と思ってたけど、謎の挙動発見。(別件だけど) とりあえずコメントで潰します。
どうも、何故かparampos[0]の値をthis.transform.position(あるいはlocalPosition)にコピーしてる場所があるっぽいですね。探すかー。
……探して見つかったのは逆パターン。つまりparampos[0]=this.transform.positionとして中身をいじってthis.transform.position=parampos[0]に戻している箇所。座標をいじくる際の常套手段なので、これは違うなぁ……通し!次!
……と、こうやってバグの原因らしきものを探してゆきます。
AIさんに聞いてみよう!
最後は、藁にも縋るつもりでChatGPTさんにコードをアップロードして「〇〇をしたいのですが何故かできません。どうすれば〇〇になりますか?」的な自然言語で状況を説明してあげます。
ここで注意したいのが、ただ「バグがあります。探してください」では、ChatGPTさんには伝わりません。なにせChatGPTさんにとっては俺ごとき人間の書くコードは「何が正常で何が異常かがわからない」からです。そこで、何度か会話をラリーして価値観を摺り合わせる会話が必要になるわけです。このへんは人間相手でも同じですね。
これで最終的に発見できれば御の字……なのですが。
おわりに
ここまで簡単にデバッグの方法をまとめてきました。
まとめてきましたけど、実はもっと効率的な手段があります。それは……
「あえて、寝るッ!」
何事も考えすぎは良くないです。テキトーなところで切り上げて睡眠を取って、改めて対峙することで良い結果が出るなら、そうした方がいいですね。
では、そんなところで、また次回。