Unity のデバッグで Unity Console にメッセージを書き込むために Debug.Log を利用していると、デフォルトではビルド後もログを書き残してしまいます。
この仕様についてメモ。
Unity - UnityEngine.Debug クラス
Unity で利用する UnityEngine.Debug
クラスを見てみると、普通のクラスのようです。リリース時やデバッグ時でなんらかの使い分けがされているわけでもなさそうです。
Android 端末から Debug.Log()
の内容を確認する 1 というような記事があるとおり、端末からデバッグとしてテキストを確認するニーズがあるため、C# の System.Diagnostics.Debug
クラスのようにリリース時は Debug
メソッドをクリアするようなことをしてくれません。(デフォルトではしてくれない)
補足として、
Assert
関係のメソッドは、Unity でもConditioal
属性UNITY_ASSERTIONS
が付与されています。
つまり、同じ名前で同じようなデバッグ機能を提供するクラスですが、動作に異なるところがあります。注意が必要です。
C# - System.Diagnostics.Debug クラス
一応ですが、C# デフォルトの System.Diagnostics.Debug クラスは、リリース時はログ(メソッド自体のコスト)を残しません。どういうことかポイントをメモ。
これは、Debug クラスのすべてのメソッドにConditional 属性で #DEBUG#
が設定されています。
本当かどうか気になる人は、Microsoft の Reference Source で Debug クラスを確認してみてください。
ログを無効にする設定変更
Debug.logger.logEnabled = false;
これも Conditioal
属性でメソッド自体をクリアしてしまうわけではないので、メソッド自体の呼び出しコストは発生します。
Debug.Log()
メソッドを呼び出すときに、文字列を処理するようなコードが書かれていたなら GC も動くことになるため、リリース時の最適化としては不十分です。
// Debug メソッドはなにもしなくても、呼び出し時点でテキスト処理がある Debug.Log($"Debug: x={x}, y={y}, z={z}, exception={ex.message}");
そんなわけで、現在の Unity 事情は Conditional
属性を与えたラッパークラスを作成する方法が一般的のようです。
スタックトレースの表示範囲の設定
Debug
の情報レベル(Error, Warning, Log, Exception など)で表示する情報をフィルタリングすることができます。
ただし、これも表示をフォルタリングをするだけなので、メソッドそのもののコストを残さないわけではありません。ログを見やすくするための機能ですね。
対策 ラッパークラスの作成
自作のラッパークラスを作成して、開発時だけ有効なメソッドになるようにします。この際は、「Micorosoft Reference Source - Debug クラス」の実装が参考になると思います。
Conditional
属性に与えるテキストは、どちらかの方法をとります。
- Unity プラットフォームの判定に利用される
UNITY_EDITOR
を指定すること - 独自の変数名を与えて、Scripting Define Symbols に変数名を追加する
なんらかの端末で動作させるとき、Log
メソッドのデフォルトは、メソッド自体を無効とします。自分が決めた変数名 (例:ENABLE_DEBUG_MODE
) が有効なときだけ、端末動作時にメソッドを有効化します。
通常時は UNITY_EDITOR
の変数名を与え、開発時(プラットフォーム)かどうかで有効/無効を切り替えるだけでよさそうです。次のコードみたいになりました。
public static class Debugger { #if !ENABLE_DEBUG_MODE private const string CONDITIONAL_TEXT = "UNITY_EDITOR"; #else private const string CONDITIONAL_TEXT = "ENABLE_DEBUG_MODE"; #endif [Conditional(CONDITIONAL_TEXT)] public static void Log(object message) { UnityEngine.Debug.Log(message); } }
ラッパークラスなので、Debug
クラスの持つ必要なメソッド(属性を持たないメソッドなど)をラップしてあげればよいと思います。
ラッパークラスの名前は、
Debug
クラスに似たような感じにしておけば、使用するときに違和感が減っていいかもしれないです。あんまり個性を出さなくてよい部分かと。
サンプル
ラッパークラスを完成させたサンプルがこちら。
ラッパークラスの拡張
せっかくラッパークラスを作ったんだから、なにか付与してもよいと思います。(アダプトっぽい感じになりますが)
デバッグのログを装飾するメソッドを用意してみるのもよいと思います。2 ただ、使い方を知っておけばいいだけの気もします。
個人的にメソッド名を Red, Green, Blue のようにしてしまうのは(細かいですが)好みではないです。C# の一般的な命名規則として採用しづらいはずです。
参考
- テラシュールブログ - ログが表示するスタックトレースの表示範囲を制限する
- 面白法人カヤック - UnityのDebug.Logの負荷とコールスタックの深さ
- Qiita - UnityEditorの時のみDebug.Logを出す方法
- テクノモンキーのアプリ開発日記 - デバッグログの出し方とログの文字色を変更する方法
Unityの教科書 Unity2019完全対応版 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)
- 作者:北村 愛実
- 発売日: 2019/06/28
- メディア: 単行本