【Unity】画面にログを表示する
端末単体でリアルタイムにログを確認できると結構便利。そんな訳で端末の画面上にログを表示してみます。
目次
サンプルコード
適当なGameObjectに以下のコンポーネントを追加してください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace mira
{
/// <summary>
/// 実機ログ表示機能。
/// </summary>
public class DisplayLog : MonoBehaviour
{
enum LogType
{
None,
Log,
Warning,
Error,
Assert,
Exception,
Num,
};
private const int LogStackNum = 100;
private Queue<string> stackLog = new Queue<string>(LogStackNum);
private BitArray logFilter = new BitArray((int)LogType.Num);
private Vector2 scrollPosition = Vector2.zero;
/// <summary>
/// 開始。
/// </summary>
void Awake()
{
ClearLogFilter();
Application.logMessageReceived += LogMessageCallBack;
}
/// <summary>
/// 破棄時。
/// </summary>
void OnDestroy()
{
Application.logMessageReceived -= LogMessageCallBack;
}
/// <summary>
/// 出力フィルターをクリアします。
/// </summary>
void ClearLogFilter()
{
logFilter.SetAll(false);
}
/// <summary>
/// 出力フィルターを設定します。
/// </summary>
void SetFilter(LogType _filterMode)
{
logFilter.Set((int)_filterMode, true);
}
/// <summary>
/// ログ通知。
/// </summary>
void LogMessageCallBack(string condition, string stackTrace, UnityEngine.LogType type)
{
string trace = null;
string color = null;
bool isFilter = false;
switch (type)
{
case UnityEngine.LogType.Log:
isFilter = logFilter.Get((int)LogType.Log);
if (isFilter || logFilter.None())
{
trace = stackTrace.Remove(0, (stackTrace.IndexOf("\n") + 1));
color = "white";
}
break;
case UnityEngine.LogType.Warning:
isFilter = logFilter.Get((int)LogType.Warning);
if (isFilter || logFilter.None())
{
trace = stackTrace.Remove(0, (stackTrace.IndexOf("\n") + 1));
color = "yellow";
}
break;
case UnityEngine.LogType.Error:
isFilter = logFilter.Get((int)LogType.Error);
if (isFilter || logFilter.None())
{
trace = stackTrace.Remove(0, (stackTrace.IndexOf("\n") + 1));
color = "red";
}
break;
case UnityEngine.LogType.Assert:
isFilter = logFilter.Get((int)LogType.Assert);
if (isFilter || logFilter.None())
{
trace = stackTrace.Remove(0, (stackTrace.IndexOf("\n") + 1));
color = "red";
}
break;
case UnityEngine.LogType.Exception:
isFilter = logFilter.Get((int)LogType.Exception);
if (isFilter || logFilter.None())
{
trace = stackTrace;
color = "red";
}
break;
}
// ログの行制限
if (stackLog.Count >= LogStackNum)
{
stackLog.Dequeue();
}
string message = string.Format("<color={0}>{1}</color> <color=white>on {2}</color>", color, condition, trace);
stackLog.Enqueue(message);
}
/// <summary>
/// ログのクリア。
/// </summary>
private void OnClearLog()
{
stackLog.Clear();
}
/// <summary>
/// ログ表示。
/// </summary>
void OnGUI()
{
if (stackLog == null || stackLog.Count == 0)
{
return;
}
Color prevColor = GUI.backgroundColor;
GUI.backgroundColor = new Color32(0x00, 0x00, 0x40, 0xDD);
float scale = (Screen.width > Screen.height) ? Screen.width / 720f : Screen.height / 720f;
GUIUtility.ScaleAroundPivot(new Vector2(scale, scale), Vector2.zero);
var centeredStyle = new GUIStyle(GUI.skin.label);
centeredStyle.alignment = TextAnchor.UpperCenter;
GUILayout.BeginArea(new Rect(0, 0, Screen.width / scale, Screen.height / scale));
GUILayout.BeginVertical(GUI.skin.box);
{
GUILayout.Label("DisplayLog");
GUILayout.BeginHorizontal(GUI.skin.box);
{
if (GUILayout.Button("Clear"))
{
OnClearLog();
}
}
GUILayout.EndHorizontal();
scrollPosition = GUILayout.BeginScrollView(scrollPosition);
foreach (string log in stackLog)
{
GUILayout.Label(log);
}
GUILayout.EndScrollView();
}
GUILayout.EndVertical();
GUILayout.EndArea();
GUI.matrix = Matrix4x4.identity;
GUI.backgroundColor = prevColor;
}
}
}
BitArrayを拡張しています。拡張内容に関してはこちらの投稿を参照してください。
テストコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Sample: MonoBehaviour
{
UnityEngine.LogType[] logTypes =
{
UnityEngine.LogType.Error,
UnityEngine.LogType.Assert,
UnityEngine.LogType.Warning,
UnityEngine.LogType.Log,
UnityEngine.LogType.Exception,
};
IEnumerator Start()
{
while (true)
{
var index = UnityEngine.Random.Range(0, logTypes.Length);
switch (logTypes[index])
{
case UnityEngine.LogType.Error:
Debug.LogError("Error " + Time.time);
break;
case UnityEngine.LogType.Assert:
Debug.Assert(false, "Assert" + Time.time);
break;
case UnityEngine.LogType.Warning:
Debug.LogWarning("Warning " + Time.time);
break;
case UnityEngine.LogType.Log:
Debug.Log("Log " + Time.time);
break;
}
yield return new WaitForSeconds(0.4f);
}
}
}
結果
画面にログを表示することができました。ログの種類によって色分けしています。