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
}
実行結果
画面に表示させると、以下のようになります
Debugと書かれたボタンを押して、表示するログレベルを変更できます
2014/07/22 追記
エディタよりに改修したバージョン を投稿しました。