【Unity】リリース時にDebug.Logを出力しないようにする

プログラマにとってログ出力は原始的で頼もしいデバッグツールです。
UnityにもConsoleウインドウに文字列を出力するためのメソッドがあります。

Debug.Log("Hello World!");

これについては説明する必要はないですね。
問題はこのメソッドが、リリースビルドでも実行されるという事実です。
Debugクラスのメソッドなので、デバッグビルドだけで機能しそうですが、リリースビルドでも機能するので、そのままだと配布したアプリでもログが出力されてしまいます。

Unityの設定でログ出力を無効にできますが、メソッドの呼び出しコストは残ってしまいます。
リリースビルドでDebugクラスのメソッドを完全に機能しないようにするには、DEBUGのシンボルで切り分けて書くか、独自のクラスでラップして使うアプローチが考えられます。

しかし、Debugクラスのメソッドを書くたびに、DEBUGで囲むのも非効率です。
独自のクラスでラップするのも、最初に設計して記述していくルールを徹底しないといけません。

この場合、Conditional属性を付けて呼び出しそのものを無効にするアプローチが便利です。
C#ではnamespaceを使わず同名クラスが定義された場合、グローバルのクラスが優先されるという特徴があります。

このコードはUnityのScripting Define SymbolsにNO_DEBUGを定義することで、UnityのDebugクラスを置き換えます。メソッドはConditional属性でDUMMYが定義されているときにしか呼び出されないので、置き換えられたクラスの中身は空になります。サードパーティのアセットのスクリプトに書かれているDebugクラスのメソッドも置き換わるので、すべての呼び出しが無効になります。

※この特徴を利用したテクニックは、有効な書き方と無効な書き方がある点に注意してください。

有効 (グローバルのDebugクラスが呼び出される)

using UnityEngine;されたコードからDebug.Log等を呼び出したとき。

無効 (UnityEngineのDebugクラスが呼び出される)

namespace UnityEngine {}の中でDebug.Log等を呼び出したとき。

UnityEngine.Debug.Logで呼び出したとき。

using Debug = UnityEngine.Debug;されてるとき。

このように、すべての書き方に万能ではありませんが、手っ取り早くログを取り除くには便利です。