1. Debug.Logの問題点
Unityでコンソールに情報を出力する関数としては以下のようなものがある。
Debug.Log();
print();
これらはリリースビルド時に除外される....ということはなく、普通に呼ばれている。
Debug.logger.logEnabled = false
でログを無効にすることができるが、メソッド呼び出しコストの発生は避けられない。呼び出し時に条件付きコンパイルで囲えば回避できるが、あまり現実的ではない。
#if UNITY_EDITOR
Debug.Log("test"); //疲れる...
#endif
2. メソッド呼び出しコストの回避
この問題に対しては、Debugクラスのラッパークラスを作成しそこからログを出力することで回避することができる。
public static class MyDebug {
[Conditional("EDITOR_MODE")]
public static void Log(string msg) => Debug.Log(msg);
}
指定した条件付きコンパイル シンボルが定義されていない場合、メソッド呼び出しまたは属性を無視するようコンパイラに指示します。
※メソッド呼び出しを無視するのであって、メソッド本体を除外する訳では無い
あとはLogWarning
, LogError
, Assert
, DrawRay
などの呼ぶ予定のあるDebugクラスメソッドをラップしていくだけだ。
どうせラッパークラスを作るなら少し改良してみる。
3. GC低減
Debug.Log
で複数のデータを文字列にする場合、文字列結合によるアロケーションが発生。
int score = 71, clearTime = 61;
Debug.Log($"score : {score} clearTime : {clearTime}");
//"score : 71 clearTime : 61"
そもそも引数の型がobject
型なので、int
やfloat
などの値型はboxingが発生する。これも同様にアロケーションが発生。
int num = 5;
Debug.Log(num);
そこで今回使用するのがZStringという文字列生成ライブラリ。
これをラッパークラスから呼び出すようにジェネリックメソッドを定義していく... (一部抜粋)
public static class MyDebug {
public const string DEBUG_CONDITIONAL_TEXT = "UNITY_EDITOR";
[Conditional(DEBUG_CONDITIONAL_TEXT)]
public static void Log(string msg) => UnityEngine.Debug.Log(msg);
[Conditional(DEBUG_CONDITIONAL_TEXT)]
public static void Log<T1>(T1 arg1) => UnityEngine.Debug.Log(ZString.Concat(arg1));
[Conditional(DEBUG_CONDITIONAL_TEXT)]
public static void Log<T1, T2>(T1 arg1, T2 arg2) => UnityEngine.Debug.Log(ZString.Concat(arg1, arg2));
[Conditional(DEBUG_CONDITIONAL_TEXT)]
public static void Log<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3) => UnityEngine.Debug.Log(ZString.Concat(arg1, arg2, arg3));
[Conditional(DEBUG_CONDITIONAL_TEXT)]
public static void Log<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
=> UnityEngine.Debug.Log(ZString.Concat(arg1, arg2, arg3, arg4));
//省略
//ZString.Concatは16引数まで定義されている
}
呼び出すときはデータを引数で渡していけばいい(便利)
int score = 71, clearTime = 61;
MyDebug.Log("score : ", score, " clearTime : ", clearTime);
//"score : 71 clearTime : 61"
4. Debugラッパークラスのデメリット
コンソールに出力されたログをクリックするとラッパークラスのDebugメソッドの場所に飛ばされる。スタックトレースからジャンプするのは少し面倒。
参考
https://tech.cygames.co.jp/archives/3383/
https://creator.game.cyberagent.co.jp/?p=8645
https://shikaku-sh.hatenablog.com/entry/unity-debug-log-optimization