16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unity3D 画面上に表示出来るログ機能(レベル付き)

Last updated at Posted at 2014-03-19

Qiita初投稿。
練習も兼ねて何か話題をと考えていたら、最近書いたUnity用のログクラスを思い出したので貼ってみます。
なお、Unity 4.3.4f1 での動作は確認しています。

元々はこちらで紹介されていた物を見て
自分ならこんな感じに・・・と実装した物です。

コード

DkLog.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// 画面表示可能なデバッグログ
///
/// [機能]
/// ・レベル分けログ
/// ・ログの画面表示+色分け表示
/// ・ボタンで表示ログレベルフィルタリング
/// ・コンソールに出さないように呼び出すことも可能(コンソールログは重いので・・・)
///
/// <example>
/// // 各レベルのログ出力(コンソールにも同時に出力)
/// DkLog.V("verbose log");
/// DkLog.D("debug log");
/// DkLog.I("information log");
/// DkLog.W("warning log");
/// DkLog.E("error log");
/// 
/// // 画面にのみ出力
/// DkLog.V("verbose log (not console)", false);
/// DkLog.D("debug log (not console)", false);
/// 
/// // 画面上にログウィンドウを表示(※ OnGUI()内での呼び出しにのみ対応)
/// DkLog.DrawLogWindow(new Rect(0, Screen.Height * 0.5f, Screen.Width * 1.0f, Screen.Height * 0.5f));
/// </example>
/// </summary>

public class DkLog : MonoBehaviour
{

    #region ///////////// タイプ /////////////

    public enum Level
    {
        Verbose,
        Debug,
        Information,
        Warning,
        Error,

        Max
    }

    private struct LogData
    {
        public Level Level { get; set; }
        public string Message { get; set; }
    }

    #endregion

    #region ///////////// 定数 /////////////

    /// 表示可能ログ最大数
    private static int LOG_MAX = 200;

    /// 各レベルのログ色
    private static Color[] LOG_COLOR =
    {
        Color.gray,
        Color.white,
        Color.cyan,
        Color.yellow,
        Color.red
    };

    #endregion

    #region ///////////// メンバ /////////////
    
    private static Level _logLevel = Level.Debug;                           // 表示対象ログレベル
    private static Queue<LogData> _logQue = new Queue<LogData>(LOG_MAX);    // ログキュー
    private static Vector2 _scrollPosition = Vector2.zero;                  // スクロールビュー位置
    private static bool _isNeedScrollReset = false;                         // スクロール位置リセットフラグ
    
    #endregion

    #region ///////////// ログ処理 /////////////

    public static void V(string message, bool isConsole = true) { _Push(Level.Verbose, message, isConsole); }
    public static void D(string message, bool isConsole = true) { _Push(Level.Debug, message, isConsole); }
    public static void I(string message, bool isConsole = true) { _Push(Level.Information, message, isConsole); }
    public static void W(string message, bool isConsole = true) { _Push(Level.Warning, message, isConsole); }
    public static void E(string message, bool isConsole = true) { _Push(Level.Error, message, isConsole); }

    /// <summary>
    /// ログを画面上に表示する
    /// OnGUI() 内で呼び出して下さい
    /// </summary>
    /// <param name="drawArea">描画対象領域(左上が0,0)</param>
    public static void DrawLogWindow(Rect drawArea)
    {
        // 下地
        GUI.Box(drawArea, "");

        GUILayout.BeginArea(drawArea);
        {
            /////////////
            // ログレベル切り替えボタン
            if (GUILayout.Button(_logLevel.ToString()))
            {
                _logLevel = (Level)((int)(_logLevel + 1) % (int)Level.Max);
                _isNeedScrollReset = true;
            }

            /////////////
            // ログスクロールビュー
            _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, true, true);

            int num = 0;
            GUIStyle style = new GUIStyle();
            foreach (LogData d in _logQue)
            {
                // ログレベルによって弾く
                if (d.Level >= _logLevel)
                {
                    // 0始まりのログ行数をプレフィックスとして付加しています
                    // 時刻にした方がいいかも
                    style.normal.textColor = LOG_COLOR[(int)d.Level];
                    GUILayout.Label(num.ToString() + " " + d.Message, style);                    
                    ++num;
                }
            }

            // ログ表示位置を先頭にリセットする
            if (_isNeedScrollReset)
            {
                _isNeedScrollReset = false;
                _scrollPosition.y = (num > 0) ? (num - 1) * 20 : 0;
            }

            GUILayout.EndScrollView();
        }
        GUILayout.EndArea();

    }

    /// <summary>
    /// ログをキューに詰める
    /// </summary>
    /// <param name="level"></param>
    /// <param name="message"></param>
    /// <param name="isConsole"></param>
    private static void _Push( Level level, string message, bool isConsole )
    {
        /////////////
        // キューが一杯だったら後ろを削除
        if (_logQue.Count >= LOG_MAX)
        {
            _logQue.Dequeue();
        }

        /////////////
        // キューに詰める
        LogData data = new LogData();
        {
            data.Level = level;
            data.Message = message;
        }
        _logQue.Enqueue(data);

        // ログ位置を調整する
        // @todo 出る度に勝手に動く。要らないかも?
        _isNeedScrollReset = true;

        /////////////
        // コンソール出力
        if (isConsole)
        {
            switch (level)
            {
                case Level.Warning: Debug.LogWarning(message); break;
                case Level.Error: Debug.LogError(message); break;
                default: Debug.Log(message); break;
            }
        }
    }

    #endregion
}

実行結果

画面に表示させると、以下のようになります

UnityLog.png

Debugと書かれたボタンを押して、表示するログレベルを変更できます

UnityLogW.png

2014/07/22 追記

エディタよりに改修したバージョン を投稿しました。

16
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?