using System.Collections.Generic; using UnityEngine; //#define USE_TESTCONSOLE /// /// A console to display Unity's debug logs in-game. /// class LogGUI : MonoBehaviour { struct Log { public string message; public string stackTrace; public LogType type; } #region Inspector Settings /// /// The hotkey to show and hide the console window. /// public KeyCode toggleKey = KeyCode.BackQuote; /// /// Whether to open the window by shaking the device (mobile-only). /// public bool shakeToOpen = true; /// /// The (squared) acceleration above which the window should open. /// public float shakeAcceleration = 3f; /// /// Whether to only keep a certain number of logs. /// /// Setting this can be helpful if memory usage is a concern. /// public bool restrictLogCount = false; /// /// Number of logs to keep before removing old ones. /// public int maxLogs = 1000; #endregion readonly List logs = new List(); Vector2 scrollPosition; bool visible; bool collapse; // Visual elements: static readonly Dictionary logTypeColors = new Dictionary { { LogType.Assert, Color.white }, { LogType.Error, Color.red }, { LogType.Exception, Color.red }, { LogType.Log, Color.white }, { LogType.Warning, Color.yellow }, }; const string windowTitle = "Console"; const int margin = 20; static readonly GUIContent clearLabel = new GUIContent("Clear", "Clear the contents of the console."); static readonly GUIContent collapseLabel = new GUIContent("Collapse", "Hide repeated messages."); readonly Rect titleBarRect = new Rect(0, 0, 10000, 20); Rect windowRect = new Rect(margin, margin, Screen.width - (margin * 2), Screen.height/3 - (margin * 2)); void OnEnable() { #if UNITY_5 Application.logMessageReceived += HandleLog; #else Application.RegisterLogCallback(HandleLog); #endif } void OnDisable() { #if UNITY_5 Application.logMessageReceived -= HandleLog; #else Application.RegisterLogCallback(null); #endif } void Update() { if (Input.GetKeyDown(toggleKey)) { visible = !visible; } if (shakeToOpen && Input.acceleration.sqrMagnitude > shakeAcceleration) { visible = true; } } void OnGUI() { //i(!visible) //{ // return; //} windowRect = GUILayout.Window(123456, windowRect, DrawConsoleWindow, windowTitle); } /// /// Displays a window that lists the recorded logs. /// /// Window ID. void DrawConsoleWindow(int windowID) { DrawLogsList(); DrawToolbar(); // Allow the window to be dragged by its title bar. GUI.DragWindow(titleBarRect); } /// /// Displays a scrollable list of logs. /// void DrawLogsList() { scrollPosition = GUILayout.BeginScrollView(scrollPosition); // Iterate through the recorded logs. for (var i = 0; i < logs.Count; i++) { var log = logs[i]; // Combine identical messages if collapse option is chosen. if (collapse && i > 0) { var previousMessage = logs[i - 1].message; if (log.message == previousMessage) { continue; } } GUI.contentColor = logTypeColors[log.type]; GUILayout.Label(log.message); } GUILayout.EndScrollView(); // Ensure GUI colour is reset before drawing other components. GUI.contentColor = Color.white; } /// /// Displays options for filtering and changing the logs list. /// void DrawToolbar() { GUILayout.BeginHorizontal(); if (GUILayout.Button(clearLabel)) { logs.Clear(); } collapse = GUILayout.Toggle(collapse, collapseLabel, GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); } /// /// Records a log from the log callback. /// /// Message. /// Trace of where the message came from. /// Type of message (error, exception, warning, assert). void HandleLog(string message, string stackTrace, LogType type) { logs.Add(new Log { message = message, stackTrace = stackTrace, type = type, }); TrimExcessLogs(); } /// /// Removes old logs that exceed the maximum number allowed. /// void TrimExcessLogs() { if (!restrictLogCount) { return; } var amountToRemove = Mathf.Max(logs.Count - maxLogs, 0); if (amountToRemove == 0) { return; } logs.RemoveRange(0, amountToRemove); } }