I have another alternative:
Create a custom “Debug” class in global space, that get’s used in release builds only and make its Log methods conditional:
#if DEBUG
#define VERBOSE
#endif
#if !UNITY_EDITOR && !VERBOSE
using UnityEngine;
using System.Diagnostics;
using System.Runtime.InteropServices;
public static class Debug {
[Conditional("VERBOSE_EXTRA")]
public static void LogInfo(string message, UnityEngine.Object obj = null) {
UnityEngine.Debug.Log(message, obj);
}
[Conditional("VERBOSE")]
public static void Log(string message, UnityEngine.Object obj = null) {
UnityEngine.Debug.Log(message, obj);
}
public static void LogWarning(string message, UnityEngine.Object obj = null) {
UnityEngine.Debug.LogWarning(message, obj);
}
public static void LogError(string message, UnityEngine.Object obj = null) {
UnityEngine.Debug.LogError(message, obj);
}
public static void LogException(System.Exception e) {
UnityEngine.Debug.LogError(e.Message);
}
}
#endif
The main advantage is, that the log usage doesn’t differ at all, so it’s easy to introduce it anytime:
Debug.Log("Somethings going on here");
Note:
I still want Warnings and Errors to be logged, so I didn’t make them conditional.
Starting with Unity 5.1, DEBUG gets defined automatically as soon as you create a development build.
Downside:
UnityEngine.Debug methods other then Log, LogInfo, LogWarning and LogError have to be issued with the complete namespace. For example:
UnityEngine.Debug.DrawLine(...);
This can easily be resolved by wrapping them all in our own Debug class. Feel free to do that, I simply was too lazy 
My thoughts on how I got to this solution:
The solutions presented so far have one thing in common, they utilize an if statement. Downsides:
- you actually have to write it out on every log occasion.
- It generates an unnecessary evaluation at runtime.
You could argue that the impact of the if statement is minimal, but that didn’t keep me from optimizing.
One way would be to use preprocessor directives, which totally work, but you’d still have to wrap every log statement with ugly code:
#if DEBUG
Debug.Log("Somethings going on here");
#endif
To get rid of this I wrote my own class, which wrapped the Log calls with conditional methods. I assume the calls don’t even exist in runtime assemblies. Something like that:
public class Logging {
[Conditional("DEBUG")]
public static void Log(string message) {
Debug.Log(message);
}
}
This works, but has these flaws:
- You have to change every “Debug.Log” call to “Logging.Log”
- In the Editor, you lose the feature of double clicking logs and jumping directly to the original place where the Log was issued, since you’ll now end up in our new Logging class all the time. This is a major time waste.
Next step: rename the Logging class to “Debug”. Since this new Debug class is in global namespace it automatically gets used instead of Unity’s UnityEngine.Debug if you use it without the complete namespace when calling it. You now don’t need to change Debug.Log calls at all, though the Editor click redirection still won’t work.
Our Debug class now prevents Logs in non DEBUG environments. As the last step I put the whole class into preprocessor statements that enable it only outside the Editor in non development builds or if you add the scripting define symbol “VERBOSE”.