문제
일반적으로 생각하는 것과는 달리, Debug Log 함수들은 디버그 빌드에서만 작동하는게 아니라 릴리즈 빌드에서도 작동한다. 이는 성능 저하로 이어지기 때문에 빌드를 하기 전에 Debug Log 함수들을 지워주는 것이 좋다.
해결방안
1. Conditional Attribute
첫 번째는 Conditional Attribute를 사용해서 컴파일 시에 Debug.Log 호출 관련된 부분들을 제외하는 방법이다.
일일이 찾아내서 지우기는 번거롭고 디버그 빌드에서 또 사용할 수도 있기 때문에, 다음과 같은 커스텀 클래스 및 함수를 작성해 Assets\Plugins 폴더 내에 저장한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class Logging
{
[System.Diagnostics.Conditional("ENABLE_LOG")]
public static void Log(object message)
{
UnityEngine.Debug.Log(message);
}
[System.Diagnostics.Conditional("ENABLE_LOG")]
public static void Log(object message, Object context)
{
UnityEngine.Debug.Log(message, context);
}
[System.Diagnostics.Conditional("ENABLE_LOG")]
public static void LogWarning(object message)
{
UnityEngine.Debug.LogWarning(message);
}
[System.Diagnostics.Conditional("ENABLE_LOG")]
public static void LogWarning(object message, Object context)
{
UnityEngine.Debug.LogWarning(message, context);
}
[System.Diagnostics.Conditional("ENABLE_LOG")]
public static void LogError(object message)
{
UnityEngine.Debug.LogError(message);
}
[System.Diagnostics.Conditional("ENABLE_LOG")]
public static void LogError(object message, Object context)
{
UnityEngine.Debug.LogError(message, context);
}
}
또한 유니티에서 Player Settings > Scripting Define Symbols에 들어가 ENABLE_LOG를 추가한다.
이렇게 하면 ENABLE_LOG 심볼이 없을때 컴파일러가 Conditional함수를 무시하기 때문에 일일이 신경써주지 않아도 된다. 하지만 빌드하기 전 꼭 Player Settings에서 심볼을 지워줘야 한다!
수동으로 지우기가 귀찮다면, 빌드 스크립트를 작성해 빌드할 때 Define symbol을 스크립트로 지워주면 된다.
빌드 스크립트를 작성하는 법은 이 글에서 다루지는 않으니, 스크립트로 빌드하는 법을 검색하는 것을 권장한다.
심볼을 스크립트로 설정하는 법을 간단하게만 설명하면 다음과 같다.
// 현재 디파인된 심볼을 얻는다.
var symbols = PlayerSettings.GetScriptingDefineSymbols(buildTarget: NamedBuildTarget.Standalone);
// 디파인 심볼을 설정한다.
// Symbols for this build target are passed as an array or as a string separated by semicolons.
PlayerSettings.SetScriptingDefineSymbols(buildTarget: NamedBuildTarget.Standalone, "ENABLE_LOG");
SetScriptingDefineSymbols
의 두 번째 인자는 string
또는 string[]
으로 넘겨주면 되는데, 심볼을 여러개 사용한다면
심볼을 세미콜론, 쉼표 또는 공백으로 구분된 하나의 string
으로 넘겨주거나 string[]
으로 넘겨주면 된다.
예를 들면 "ENABLE_LOG;MY_SYMBOL"
등으로 하면 된다.
사용할때는 다음과 같이 하면 된다.
Logging.Log("로그입니다");
Logging.LogWarning("워닝 로그입니다");
혹은 클래스 이름을 그대로 Debug로 사용하고 싶다면 아래와 같이 namespace와 using을 활용한다.
namespace MyGame
{
// 클래스 이름을 Debug로 변경하고 내용은 동일하다.
public static class Debug
{ ... }
}
// 상단 using문
using Debug = MyGame.Debug;
// 함수 내에서 이렇게 사용하면 된다.
Debug.Log("로그입니다");
심볼 관련 추가 및 제거도 귀찮다면 에디터에서 이미 정의되어있는 UNITY_EDITOR
심볼을 사용하는 것도 나름 괜찮은 방법일 것이다.
[System.Diagnostics.Conditional("UNITY_EDITOR")]
public static void Log(object message)
{
UnityEngine.Debug.Log(message);
}
2. Debug.unityLogger.logEnabled = false
두 번째는 Debug.unityLogger.logEnabled = false를 어딘가에서 호출해줘서 로깅 기능을 꺼주는 것이다.
이는 함수 호출은 하되 런타임에 디버그 로그 작동을 안하게 해주는 것이다.
다만 이런 특징 때문에 Debug.Log 함수에 넘어가는 매개변수가 연산된다는 것인데,
(예를 들면 흔히 많이 사용하는 문자열 formatting, concatenation 등등)
이 점 제외하곤 개인적인 생각으론 유의미하게 큰 차이는 없을 듯 하다.
(그래도 함수 호출이라는게 공짜로 되는건 아니긴 하지만...)
또 다른 문제
에디터 콘솔에서 로그를 더블 클릭을 하면 호출한 곳이 아니라 커스텀 디버그 클래스 파일이 열린다. 이에 대한 해결 방안은 아래 글을 참고하자.