134 lines
4.8 KiB
C#
134 lines
4.8 KiB
C#
|
// People should be able to see and report errors to the developer very easily.
|
|||
|
//
|
|||
|
// Unity's Developer Console only works in development builds and it only shows
|
|||
|
// errors. This class provides a console that works in all builds and also shows
|
|||
|
// log and warnings in development builds.
|
|||
|
//
|
|||
|
// Note: we don't include the stack trace, because that can also be grabbed from
|
|||
|
// the log files if needed.
|
|||
|
//
|
|||
|
// Note: there is no 'hide' button because we DO want people to see those errors
|
|||
|
// and report them back to us.
|
|||
|
//
|
|||
|
// Note: normal Debug.Log messages can be shown by building in Debug/Development
|
|||
|
// mode.
|
|||
|
using UnityEngine;
|
|||
|
using System.Collections.Generic;
|
|||
|
|
|||
|
namespace Mirror
|
|||
|
{
|
|||
|
struct LogEntry
|
|||
|
{
|
|||
|
public string message;
|
|||
|
public LogType type;
|
|||
|
|
|||
|
public LogEntry(string message, LogType type)
|
|||
|
{
|
|||
|
this.message = message;
|
|||
|
this.type = type;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public class GUIConsole : MonoBehaviour
|
|||
|
{
|
|||
|
public int height = 80;
|
|||
|
public int offsetY = 40;
|
|||
|
|
|||
|
// only keep the recent 'n' entries. otherwise memory would grow forever
|
|||
|
// and drawing would get slower and slower.
|
|||
|
public int maxLogCount = 50;
|
|||
|
|
|||
|
// Unity Editor has the Console window, we don't need to show it there.
|
|||
|
// unless for testing, so keep it as option.
|
|||
|
public bool showInEditor = false;
|
|||
|
|
|||
|
// log as queue so we can remove the first entry easily
|
|||
|
readonly Queue<LogEntry> log = new Queue<LogEntry>();
|
|||
|
|
|||
|
// hotkey to show/hide at runtime for easier debugging
|
|||
|
// (sometimes we need to temporarily hide/show it)
|
|||
|
// Default is BackQuote, because F keys are already assigned in browsers
|
|||
|
[Tooltip("Hotkey to show/hide the console at runtime\nBack Quote is usually on the left above Tab\nChange with caution - F keys are generally already taken in Browsers")]
|
|||
|
public KeyCode hotKey = KeyCode.BackQuote;
|
|||
|
|
|||
|
// GUI
|
|||
|
bool visible;
|
|||
|
Vector2 scroll = Vector2.zero;
|
|||
|
|
|||
|
// only show at runtime, or if showInEditor is enabled
|
|||
|
bool show => !Application.isEditor || showInEditor;
|
|||
|
|
|||
|
void Awake()
|
|||
|
{
|
|||
|
// only show at runtime, or if showInEditor is enabled
|
|||
|
if (show)
|
|||
|
Application.logMessageReceived += OnLog;
|
|||
|
}
|
|||
|
|
|||
|
// OnLog logs everything, even Debug.Log messages in release builds
|
|||
|
// => this makes a lot of things easier. e.g. addon initialization logs.
|
|||
|
// => it's really better to have than not to have those
|
|||
|
void OnLog(string message, string stackTrace, LogType type)
|
|||
|
{
|
|||
|
// is this important?
|
|||
|
// => always show exceptions & errors
|
|||
|
// => usually a good idea to show warnings too, otherwise it's too
|
|||
|
// easy to miss OnDeserialize warnings etc. in builds
|
|||
|
bool isImportant = type == LogType.Error || type == LogType.Exception || type == LogType.Warning;
|
|||
|
|
|||
|
// use stack trace only if important
|
|||
|
// (otherwise users would have to find and search the log file.
|
|||
|
// seeing it in the console directly is way easier to deal with.)
|
|||
|
// => only add \n if stack trace is available (only in debug builds)
|
|||
|
if (isImportant && !string.IsNullOrWhiteSpace(stackTrace))
|
|||
|
message += $"\n{stackTrace}";
|
|||
|
|
|||
|
// add to queue
|
|||
|
log.Enqueue(new LogEntry(message, type));
|
|||
|
|
|||
|
// respect max entries
|
|||
|
if (log.Count > maxLogCount)
|
|||
|
log.Dequeue();
|
|||
|
|
|||
|
// become visible if it was important
|
|||
|
// (no need to become visible for regular log. let the user decide.)
|
|||
|
if (isImportant)
|
|||
|
visible = true;
|
|||
|
|
|||
|
// auto scroll
|
|||
|
scroll.y = float.MaxValue;
|
|||
|
}
|
|||
|
|
|||
|
void Update()
|
|||
|
{
|
|||
|
if (show && Input.GetKeyDown(hotKey))
|
|||
|
visible = !visible;
|
|||
|
}
|
|||
|
|
|||
|
void OnGUI()
|
|||
|
{
|
|||
|
if (!visible) return;
|
|||
|
|
|||
|
// If this offset is changed, also change width in NetworkManagerHUD::OnGUI
|
|||
|
int offsetX = 300 + 20;
|
|||
|
|
|||
|
GUILayout.BeginArea(new Rect(offsetX, offsetY, Screen.width - offsetX - 10, height));
|
|||
|
|
|||
|
scroll = GUILayout.BeginScrollView(scroll, "Box", GUILayout.Width(Screen.width - offsetX - 10), GUILayout.Height(height));
|
|||
|
foreach (LogEntry entry in log)
|
|||
|
{
|
|||
|
if (entry.type == LogType.Error || entry.type == LogType.Exception)
|
|||
|
GUI.color = Color.red;
|
|||
|
else if (entry.type == LogType.Warning)
|
|||
|
GUI.color = Color.yellow;
|
|||
|
|
|||
|
GUILayout.Label(entry.message);
|
|||
|
GUI.color = Color.white;
|
|||
|
}
|
|||
|
GUILayout.EndScrollView();
|
|||
|
|
|||
|
GUILayout.EndArea();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|