blog

DeNAのエンジニアが考えていることや、担当しているサービスについて情報発信しています

2022.06.02 技術記事

Unityでデバッグ基盤を作るうえでの勘所

by Ryuya Matsuda

#Unity

テクノロジー推進グループ Graphics Engineer Team の松田です。

私の所属するGraphics Engineer Team(通称GRET)は、ゲーム事業全体のグラフィックスに関する技術を一手に引き受ける専門チームです。 各タイトルでの開発から、共通基盤の開発、数年後に必要になるであろう技術の研究まで幅広く活動しています。

本記事ではGRETの活動の中で私が実現した、Unity用のデバッグ基盤「DebugPrint」の紹介と、デバッグ基盤を作るうえでの勘所を紹介していきます。

なお、DebugPrintは現時点ではソースコードの公開はしておりません。 デバッグ基盤を作るうえでの取捨選択の参考にしていただけたら幸いです。

実機デバッグの難しさ

この記事を読んでいただいている方の中にも、Unity開発の実機デバッグで苦労した経験のある方がいると思います。

UnityのEditor上であれば、InspectorやConsoleなどで値やフレームバッファを確認することもできますが、モバイル端末などの実機上では、画面に描画しないとリアルタイムでの状態確認が難しかったりします。

UnityにはuGUIやOnGUIといった便利なGUI機能が用意されていますが、これらはあらかじめUnityのシーン上にオブジェクトを複数準備する必要があったり、パフォーマンス面で難があったりと、使うための事前準備や気を付けないといけない事が多々ありました。

実機上でデバッグ用に情報を表示しようとすると、Unityのシーン上にCanvasを追加して、子要素に情報を割り当てできるようにプログラムを書き換えて、見やすいようにCanvasの設定を更新して、確認が終わったら消して…と、意外と手間がかかります。

1つ1つの作業自体は簡単でも「ちょっと表示して確認したい」が意外と面倒な作業でした。

そこで、ゲームを作る人がそれらの行程に余計な時間を割くことなく、よりゲーム開発の本質に集中できるようにするため、簡単なデバッグ表示機能の基盤としてDebugPrintを開発しました。

DebugPrintとは

DebugPrintは1行のコードでUnityの画面上にデバッグ表示ができるというものです。

このように1行のコードで画像を指定してあげるだけで、画面上に任意の画像を表示できるようになります。

図形や文字、画像などを手軽に画面に表示して開発を効率化するための機能で、簡易デバッグだけでなく、タイトルに合わせたより高級なデバッグ機能の実装基盤として利用されることも想定しています。

デバッグ基盤を作る上での勘所

DebugPrintはデバッグのための機能なので、開発者のこだわりより利用者の使いやすさ、機能の充実より必要最低限の機能があり軽量であることを重視しています。

リリースに影響させない

シンボルを定義することでDebugPrintを一括で除外できるようにしました。

このあたりは利用者に委ねてしまっても良いのですが、DebugPrint自体がデバッグのための機能ということで、うっかりリリースビルドに含まれてしまうことが無いよう、提供する全ての機能で指定のシンボルを定義するとコンパイル時に除外されるようにしています。

チーム開発ではほとんどの場合で、デバッグとリリースでそれぞれビルドプロセスを定義しておくと思うので、リリースビルドの際はDebug Printを除外するシンボルを定義することで、ビルドタイプを意識することなく利用できると思います。

負荷のボトルネックにしない

Debug用の機能がゲームの負荷になってしまっては本末転倒です。

ゲームの最適化でボトルネックの特定に余計な時間がかかってしまったり、ゲーム体験がリリースビルドと異なることで本当に解決しないといけない問題の発見が遅れたりするからです。

そのため、デバッグに必ずしも必要でない機能は、余計な負荷の原因になる可能性があるため、DebugPrintには含めないようにしています。

また、DebugPrintは近年リリースされているようなタイトルで、サポート対象の下限となる端末でも快適に動作することを目標に描画負荷とC#レベルのチューニングを行っています。

特に描画周りでは、矩形や線もテキストと同じマテリアルで表現することで、同一のメッシュにBatchを行い、1度の描画命令で書きれるようにする工夫をしました。

画像以外の描画処理がバッチされている

一方で、負荷が高くなることは分かっているものの、利用される場面が少なくチューニングの費用対効果が良くない使い方に関しては、初めからサポート外としてドキュメントに明記することにしました。

導入して見つかった課題と解決

テキストの視認性

画面によって背景色にテキストが馴染んでしまい見えにくいという問題がありました。

テキストの装飾は必ずしも必要ではない機能だったため、パフォーマンスと天秤にかけて落としていましたが、視認性向上のためアウトラインを選択できるようにした。

アウトライン表現は、テキストの複製をメインのテキストの周囲八方向にずらすして縁を表現するのがメジャーな手法だと思いますが、 この手法はアウトラインの太さの調整が多少できる反面、元のテキストの9倍ほどの描画負荷がかかってしまうため、大量に表示した場合に大きな負荷になってしまいます。

そこで、縁表現用のテキストの複製を斜め方向のみに減らし、アウトラインの太さは固定にする制約をつけることで、見た目の担保と負荷の軽減を行いました。

DebugPrint座標への変換

DebugPrintは定義された二次元座標で、表示位置の指定ができるようになっています。

この二次元座標は、画面の任意の位置に表示するだけであれば直感的に指定できますが、ディスプレイ上のタッチジェスチャーの位置や3D空間上のオブジェクトが表示されている位置など、DebugPrintとは異なる座標系での位置をDebugPrint上で反映させるたい場合、導入タイトルのUnityエンジニアが座標変換の計算をする必要がありました。

計算自体はそこまで複雑ではありませんが、DebugPrint座標の理解と座標変換の知識が必要となるため、より多くのUnityエンジニアが利用することを考えて、座標変換のヘルパーを用意することにしました。

今後

Debug Printはプロジェクトに導入されたばかりなので、まだまだ使いづらかったり、品質が足りてなかったりしていると思います。
実際に導入したタイトルからのFBを貰いながら、今以上に使いやすくなるよう改善していけたらと思います。

また、Debug Printに限らず、今後もこのような開発現場で役立つ機能を充実させていきたいです。

最後まで読んでいただき、ありがとうございます!
この記事をシェアしていただける方はこちらからお願いします。

recruit

DeNAでは、失敗を恐れず常に挑戦し続けるエンジニアを募集しています。