GUIConsole.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // People should be able to see and report errors to the developer very easily.
  2. //
  3. // Unity's Developer Console only works in development builds and it only shows
  4. // errors. This class provides a console that works in all builds and also shows
  5. // log and warnings in development builds.
  6. //
  7. // Note: we don't include the stack trace, because that can also be grabbed from
  8. // the log files if needed.
  9. //
  10. // Note: there is no 'hide' button because we DO want people to see those errors
  11. // and report them back to us.
  12. //
  13. // Note: normal Debug.Log messages can be shown by building in Debug/Development
  14. // mode.
  15. using UnityEngine;
  16. using System.Collections.Generic;
  17. namespace Mirror
  18. {
  19. struct LogEntry
  20. {
  21. public string message;
  22. public LogType type;
  23. public LogEntry(string message, LogType type)
  24. {
  25. this.message = message;
  26. this.type = type;
  27. }
  28. }
  29. public class GUIConsole : MonoBehaviour
  30. {
  31. public int height = 80;
  32. public int offsetY = 40;
  33. // only keep the recent 'n' entries. otherwise memory would grow forever
  34. // and drawing would get slower and slower.
  35. public int maxLogCount = 50;
  36. // Unity Editor has the Console window, we don't need to show it there.
  37. // unless for testing, so keep it as option.
  38. public bool showInEditor = false;
  39. // log as queue so we can remove the first entry easily
  40. readonly Queue<LogEntry> log = new Queue<LogEntry>();
  41. // hotkey to show/hide at runtime for easier debugging
  42. // (sometimes we need to temporarily hide/show it)
  43. // Default is BackQuote, because F keys are already assigned in browsers
  44. [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")]
  45. public KeyCode hotKey = KeyCode.BackQuote;
  46. // GUI
  47. bool visible;
  48. Vector2 scroll = Vector2.zero;
  49. // only show at runtime, or if showInEditor is enabled
  50. bool show => !Application.isEditor || showInEditor;
  51. void Awake()
  52. {
  53. // only show at runtime, or if showInEditor is enabled
  54. if (show)
  55. Application.logMessageReceived += OnLog;
  56. }
  57. // OnLog logs everything, even Debug.Log messages in release builds
  58. // => this makes a lot of things easier. e.g. addon initialization logs.
  59. // => it's really better to have than not to have those
  60. void OnLog(string message, string stackTrace, LogType type)
  61. {
  62. // is this important?
  63. // => always show exceptions & errors
  64. // => usually a good idea to show warnings too, otherwise it's too
  65. // easy to miss OnDeserialize warnings etc. in builds
  66. bool isImportant = type == LogType.Error || type == LogType.Exception || type == LogType.Warning;
  67. // use stack trace only if important
  68. // (otherwise users would have to find and search the log file.
  69. // seeing it in the console directly is way easier to deal with.)
  70. // => only add \n if stack trace is available (only in debug builds)
  71. if (isImportant && !string.IsNullOrWhiteSpace(stackTrace))
  72. message += $"\n{stackTrace}";
  73. // add to queue
  74. log.Enqueue(new LogEntry(message, type));
  75. // respect max entries
  76. if (log.Count > maxLogCount)
  77. log.Dequeue();
  78. // become visible if it was important
  79. // (no need to become visible for regular log. let the user decide.)
  80. if (isImportant)
  81. visible = true;
  82. // auto scroll
  83. scroll.y = float.MaxValue;
  84. }
  85. void Update()
  86. {
  87. if (show && Input.GetKeyDown(hotKey))
  88. visible = !visible;
  89. }
  90. void OnGUI()
  91. {
  92. if (!visible) return;
  93. // If this offset is changed, also change width in NetworkManagerHUD::OnGUI
  94. int offsetX = 300 + 20;
  95. GUILayout.BeginArea(new Rect(offsetX, offsetY, Screen.width - offsetX - 10, height));
  96. scroll = GUILayout.BeginScrollView(scroll, "Box", GUILayout.Width(Screen.width - offsetX - 10), GUILayout.Height(height));
  97. foreach (LogEntry entry in log)
  98. {
  99. if (entry.type == LogType.Error || entry.type == LogType.Exception)
  100. GUI.color = Color.red;
  101. else if (entry.type == LogType.Warning)
  102. GUI.color = Color.yellow;
  103. GUILayout.Label(entry.message);
  104. GUI.color = Color.white;
  105. }
  106. GUILayout.EndScrollView();
  107. GUILayout.EndArea();
  108. }
  109. }
  110. }