블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2797)
Unity3D (853)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (61)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

[추가] 2024-04-17

#define으로 Editor, Device등 원하는 곳에 띄울 수 있게 약간 변형함

#if UNITY_EDITOR
#define MY_DEBUG
#endif

using UnityEngine;
using System.Collections;
using System;
using UnityEngine.Internal;


/// 
/// It overrides UnityEngine.Debug to mute debug messages completely on a platform-specific basis.
/// 
/// Putting this inside of 'Plugins' foloder is ok.
/// 
/// Important:
///     Other preprocessor directives than 'UNITY_EDITOR' does not correctly work.
/// 
/// Note:
///     [Conditional] attribute indicates to compilers that a method call or attribute should be 
///     ignored unless a specified conditional compilation symbol is defined.
/// 
/// See Also: 
///     http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx
/// 
/// 2012.11. @kimsama
///

/// - Unity 5.x 대응(5.x에 추가된 Debug 함수 추가)
/// - isDebugBuild("Development Build") 시 return.
/// 2016-07-25 by blueasa

public static class Debug
{
    public static bool developerConsoleVisible
    {
        get { return UnityEngine.Debug.developerConsoleVisible; }
    }

    public static bool isDebugBuild
    {
        //get { return UnityEngine.Debug.isDebugBuild; }
#if MY_DEBUG
        get { return true; }
#else
        get { return false; }
#endif
    }

    public static ILogger logger
    {
        get { return UnityEngine.Debug.unityLogger; }
    }

    public static void Assert(bool condition)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.Assert(condition);
    }

    public static void Assert(bool condition, string message)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.Assert(condition, message);
    }

    public static void Assert(bool condition, object message)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.Assert(condition, message);
    }

    public static void Assert(bool condition, UnityEngine.Object context)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.Assert(condition, context);
    }

    public static void Assert(bool condition, string message, UnityEngine.Object context)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.Assert(condition, message, context);
    }

    public static void Assert(bool condition, object message, UnityEngine.Object context)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.Assert(condition, message, context);
    }

    public static void AssertFormat(bool condition, string format, params object[] args)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.AssertFormat(condition, format, args);
    }

    public static void AssertFormat(bool condition, UnityEngine.Object context, string format, params object[] args)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.AssertFormat(condition, context, format, args);
    }

    public static void Break()
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.Break();
    }

    public static void ClearDeveloperConsole()
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.ClearDeveloperConsole();
    }

    public static void DebugBreak()
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.DebugBreak();
    }

    public static void DrawLine(Vector3 start, Vector3 end)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.DrawLine(start, end);
    }

    public static void DrawLine(Vector3 start, Vector3 end, Color color)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.DrawLine(start, end, color);
    }

    public static void DrawLine(Vector3 start, Vector3 end, Color color, float duration)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.DrawLine(start, end, color, duration);
    }

    public static void DrawLine(Vector3 start, Vector3 end, [DefaultValue("Color.white")] Color color, [DefaultValue("0.0f")] float duration, [DefaultValue("true")] bool depthTest)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.DrawLine(start, end, color, duration, depthTest);
    }

    public static void DrawRay(Vector3 start, Vector3 dir)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.DrawRay(start, dir);
    }

    public static void DrawRay(Vector3 start, Vector3 dir, Color color)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.DrawRay(start, dir, color);
    }

    public static void DrawRay(Vector3 start, Vector3 dir, Color color, float duration)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.DrawRay(start, dir, color, duration);
    }

    public static void DrawRay(Vector3 start, Vector3 dir, [DefaultValue("Color.white")] Color color, [DefaultValue("0.0f")] float duration, [DefaultValue("true")] bool depthTest)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.DrawRay(start, dir, color, duration, depthTest);
    }

    public static void Log(object message)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.Log(message);
    }

    public static void Log(object message, UnityEngine.Object context)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.Log(message, context);
    }

    public static void LogAssertion(object message)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogAssertion(message);
    }

    public static void LogAssertion(object message, UnityEngine.Object context)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogAssertion(message, context);
    }

    public static void LogAssertionFormat(string format, params object[] args)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogAssertionFormat(format, args);
    }

    public static void LogAssertionFormat(UnityEngine.Object context, string format, params object[] args)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogAssertionFormat(context, format, args);
    }

    public static void LogError(object message)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogError(message);
    }

    public static void LogError(object message, UnityEngine.Object context)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogError(message, context);
    }

    public static void LogErrorFormat(string format, params object[] args)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogErrorFormat(format, args);
    }

    public static void LogErrorFormat(UnityEngine.Object context, string format, params object[] args)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogErrorFormat(context, format, args);
    }

    public static void LogException(Exception exception)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogException(exception);
    }

    public static void LogException(string exception)
    {
        Exception ex = new Exception(exception);
        UnityEngine.Debug.LogException(ex);
    }

    public static void LogException(Exception exception, UnityEngine.Object context)
    {
        //if (false == isDebugBuild)
        //    return;

        UnityEngine.Debug.LogException(exception, context);
    }

    public static void LogFormat(string format, params object[] args)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.LogFormat(format, args);
    }

    public static void LogFormat(UnityEngine.Object context, string format, params object[] args)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.LogFormat(context, format, args);
    }

    public static void LogWarning(object message)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.LogWarning(message);
    }

    public static void LogWarning(object message, UnityEngine.Object context)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.LogWarning(message, context);
    }

    public static void LogWarningFormat(string format, params object[] args)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.LogWarningFormat(format, args);
    }

    public static void LogWarningFormat(UnityEngine.Object context, string format, params object[] args)
    {
        if (false == isDebugBuild)
            return;

        UnityEngine.Debug.LogWarningFormat(context, format, args);
    }
}

 

 

 

----

Unity에서 프로그래밍할 때 콘솔에 디버깅이나 경고 혹은 에러 문자열 출력을 위해서 Debug.Log 의 메시지 출력 메소드를 많이 사용합니다. 
 
문제는 Debug.Log 메소드의 이름과 달리 해당 콘솔 출력이 디바이스에 deploy해서 실행할 때에도 실행이 된다는 점입니다. 
 
처음부터 Debug.Log 메시지를 대체하는 별도의 wrapper 클래스나 메소드를 작성해서 사용한 경우라면 문제가 되지 않지만, 프로젝트 내에 이미 수 많은 Debug.Log 메시지들이 존재하는 경우, 변경이 번거로울 수 있습니다. 
 
이 때 사용할 수 있는 간단한 방법이 .NET의 System.Diagnostics.Conditional 속성을 사용하는 것입니다.
 
public static class Debug
{ 
[System.Diagnostics.Conditional("UNITY_EDITOR")]
public static void Log (object message)
{
UnityEngine.Debug.Log (message);
}
}
 
전체 코드는 아래 링크의 gist에서 확인할 수 있습니다.
 
 
Debug 클래스에는 Debug.Log 뿐만 아니라 UnityEngine.Debug 클래스의 DrawLine, DrawRay 등을 포함한 모든 메소드들에 대한 대체 메소드들을 포함하고 있습니다.
 
사용 방법은 링크의 전체 코드를 Assets 폴더 내의 Editor 폴더에 저장하면 됩니다.
사용 방법은 링크의 전체 코드를 Assets 폴더 내의 Plugins 폴더에 저장하면 됩니다.

 

 

[출처] http://www.unitystudy.net/bbs/board.php?bo_table=writings&wr_id=60&page=0&sca=&sfl=&stx=&spt=0&page=0&cwin=#c_322

 

 

 

[추가][Unity 5.3 이상]

It works.
And, Unity 5.3 provides an easier solution: Debug.logger.logEnabled=false to disable it.



[출처] https://gist.github.com/kimsama/4123043

 

반응형
Posted by blueasa
, |

디버거로 프로그램 실행 도중 변수 값 조정 방법

 

작성자 : 최흥배 ( jacking75@gmail.com )
 

이 기법은 Game Coding Complete ”라는 책에서 디버깅 기법 중 하나로 소개되고 있는 기법으로 프로그램을 디버깅 모드로 실행하면서 어떤 변수의 값을 변경하 여그 결과를 바로 알고 싶을 때 아주 좋다.

일반적으로 UI 작업 같은 것을 해보면 컨트롤 등의 위치를 바르게 잡기 위해 위치 값을 변경하면서 컴파일->실행->수정->컴파일 단계를 반복하면서 정확한 값을 알아내기 때문에 상당한 시간과 짜증이 유발 된다.

이외에 데이터 주도방식으로 프로그래밍 해도 되지만 이것도 데이터변경->실행 단계를 계속 반복 해야 되기 때문에 UI 노가다 작업이 만만치 않을 것이다.

그러나 지금 소개하는 기법을 사용하면 아주 손쉽고 바로 그 결과를 알 수 있다.


 

이 기법을 사용 하려면 static 변수를 사용하여 디버깅 시 static 변수를 사용하는 부분에 브레이크 포인트를 걸고 변수를 조정하면 된다.



위의 그림을 보면 static 변수 nn0에 값을 설정 한 후 이 값을 사용하는 280 라인에 브레이크 포인트를 걸어 놓는다.

그런 후 디버깅 시에 280 라인에서 프로그램이 멈추면 디버깅 창의 “자동(Watch) ”창에서 nn0 변수를 찾은 후 값을 원하는 값으로 변경한다.




nn0의 값은 원래는 53 이었으나 이제 60으로 변경 되어 이후 60으로 설정 되어 프로그램에서 사용된다.


 

위 그림의 코드를 보면 알겠지만 위 코드는 화면에 글자를 찍기 위한 코드인데 화면에서 글자를 찍을 때 위치에 맞게 하기 위해서 x,y 좌표를 변경하면서 결과를 바로 보기 때문에 아주 빠르고 쉽게 작업이 된다.

출처 : 
http://jacking.tistory.com/301

 

반응형
Posted by blueasa
, |
C++을 사용하시는 분들은 VC계열에서 전처리자을 이용하는 방법에 대해서 익숙하신 분들이 많으실겁니다. 
특히 전처리자, #define, #if ~ #endif등을 이용해서 디버그할때만 필요한 코드를 릴리즈할때 무시하도록 하는 일은 한번쯤은 해보셨지 않았나 싶습니다. 

C#으로 넘어오면서 네임스페이스등의 개념이 본격적으로 사용되고 전처리자를 잘 사용하지 않게 되었습니다. 하지만 코드를 짜다보니 여전히 디버그용으로 만든 코드가 릴리즈에 포함되지 않게 하는일이 필요하더군요. 그래서 어떻게 쓸수있지 않을까 고민하던 중에 다음과 같은방법을 발견했습니다. 

using System; 
using System.Diagnostics; 

class Program { 
    static void Main(string[] args) { 

        #if DEBUG 
        DebugMethod1(); 
        #endif 

        DebugMethod2(); 
        Console.ReadKey(); 
    } 
    static void DebugMethod1() { 
        Console.WriteLine("Debug1"); 
    } 

    [Conditional("DEBUG")] 
    static void DebugMethod2() { 
        Console.WriteLine("Debug2"); 
    } 
}

from : Eric Gunnerson's C# Compendium
         http://blogs.msdn.com/ericgu/archive/2004/08/13/214175.aspx


빨갛게 된 부분을 주목해주세요, 위의 전처리자를 이용한 방법은 코드라인 일부를 디버그 모드에서 활성화하기 위해 감싸는 것입니다. VS에서 릴리즈 모드 컴파일로 들어가면 위 전처리자 사이의 코드는 회색으로 변하면서 실행이 안됩니다. 아래 Attribute를 사용하는 방법은 메소드 전체를 디버그모드에서만 컴파일 하기 위해 사용하는 것입니다. 이러한 팁은 매우 간단하지만 많은 분들이 모르시더라구요... 역시 구글검색은 안나오는게 없는것 같습니다. ^^

 좀더 덧붙이자면, C#에는 전처리 과정이 없기 때문에 컴파일 과정에서 무시되는것 같습니다. 그리고 뒤의 Attribute를 사용하는 방법은 문제가 있는데 함수의 return값이 void 이어야만 하고 public 메소드를 저렇게 만들게 되면 나중에 잡기힘든 버그가 발생 (분명 실행시켰는데 실행조차 안되는) 한답니다. 참고하세요.


반응형
Posted by blueasa
, |