Feel Physics Backyard

HoloLensの出張授業をする会社で、教材を開発しています

C#で、UnityのDebug.Logでメッセージに加えてファイル名と行数を表示する

「〆切が近いのに、時間をかけてヘルパークラスを作ってしまった…」

「あほか!」

そんな大したものではないのですが、こんな感じです:

f:id:weed_7777:20170803225933p:plain

要するに、以下のクラスファイルをプロジェクトに入れるだけで、DebugLog

  1. メッセージに加えて
  2. ファイル名
  3. 行数

表示します。

2018年3月16日加筆:

以下のプログラムだとコンソールでダブルクリックしてもソースコードの該当行に飛びません(MyHelper.csが開いてしまう)。そこで以下のように変えました:

    static public class MyHelper
    {

        public static string FileAndMethodNameWithMessage(string message)
        {
            StackFrame sf = new StackFrame(1, true);

            String methodName = sf.GetMethod().ToString();

            List<string> filePathElementList = new List<string>();
            filePathElementList.AddRange(sf.GetFileName().Split('\\'));
            String fileName = filePathElementList.Last();

            int lineNumber = sf.GetFileLineNumber();
            return fileName + "(" + lineNumber + "): " + methodName + " が呼び出されました。" + message;
        }
    }

使うときは以下のように使います:

Debug.Log(MyHelper.FileAndMethodNameWithMessage("「Room for 1」をロードします"));
Debug.LogError(MyHelper.FileAndMethodNameWithMessage("アリーナをロードしようとしていますが、我々はマスタークライアントではありません"));

以下のようにコンソールに出力されます:

Launcher.cs(173): Void OnJoinedRoom() が呼び出されました。「Room for 1」をロードします

もちろんダブルクリックすれば該当ファイルの該当行へ飛びます。

加筆は以上です。


あと、もう一つの機能として、表示・非表示のBooleanを引数に入れます。

なぜこんなことをしているかというと、デバッグログ表示・非表示のBoolean変数を用意しておいて、開発中はtrue、Production時にはfalseにすれば、Production時にはすべてのデバッグログが抑制されます

こんな風に使います:

...

Boolean shouldDebugLog = true;

...

MyHelper.DebugLog(GrobalVar.shouldDebugLog, "Are you tired?");
MyHelper.DebugLog(GrobalVar.shouldDebugLog, "Yes, I'm exhausted.");
MyHelper.DebugLog(GrobalVar.shouldDebugLog, "Let's eat Unagi!");

...

上記の通りMyHelperという静的クラスを用意し、クラスメソッドDebugLogを実装しています。その実装が以下です。

更新しました

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Diagnostics;
using System.Linq;

// グローバル定数
public static class GlobalVar
{
    public const Boolean shouldDebugLog = true;
    public const Boolean shouldDebugLogInScene = true;
}

// 俺々ヘルパークラス
static public class MyHelper
{
    // コンソールでデバッグ
    public static void DebugLog(String message)
    {
#if UNITY_EDITOR
        if (GlobalVar.shouldDebugLog)
        {
            StackFrame sf = new StackFrame(1, true);

            //String methodName = sf.GetMethod().ToString();  // 未使用

            List<string> filePathElementList = new List<string>();
            filePathElementList.AddRange(sf.GetFileName().Split('\\'));
            String fileName = filePathElementList.Last();

            int lineNumber = sf.GetFileLineNumber();
            UnityEngine.Debug.Log(message + ": " + fileName + "(" + lineNumber + ")");
        }
#endif
    }

    // シーンオブジェクト(3Dテキスト)でデバッグ
    public static void DebugLogInScene(String logObjectName, String message)
    {
        if (GlobalVar.shouldDebugLogInScene)
        {
            TextMesh tm = GameObject.Find(logObjectName).GetComponent<TextMesh>();
            tm.text = message;
        }
    }
}

以下はコンパイルエラーが出る古い版です

// MyHelper.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Diagnostics;
using System.Linq;

static public class MyHelper
{
    public static void DebugLog(Boolean shouldDebugLog, String message)
    {
        if (shouldDebugLog)
        {
            StackFrame sf = new StackFrame(1, true);

            //String methodName = sf.GetMethod().ToString();  // 未使用

            List<string> filePathElementList = new List<string>();
            filePathElementList.AddRange(sf.GetFileName().Split('\\'));
            String fileName = filePathElementList.Last();

            int lineNumber    = sf.GetFileLineNumber();
            UnityEngine.Debug.Log(message + ": " + fileName + "(" + lineNumber + ")");
        }
    }
}

まあ、コードは上記の通りですが、何も考えずにコピペして下さい😁ちょっとラクになります。

ご参考になれば幸いです。

あさってのMaker Faire Tokyo 2017Microsoft HoloLensのアプリを出展するのですが、何とか間に合いそう。F-01-02ブースです。ぜひ気軽においで下さい。ウナギ食べたい…