Unity 游戏框架搭建 (九) 减少加班利器-QConsole

毛要实现这个工具?
  1.在我小时候,每当游戏在真机运行时,我们看到的日志是这样的。

        

       没高亮啊,还有乱七八糟的堆栈信息,好干扰日志查看,好影响心情。

  2.还有就是必须始终连着usb线啊,我想要想躺着测试。。。
以上种种原因,QConsole诞生了。

如何使用?
    使用方式和QLog一样,在初始化出调用,简单的一句。
[C#]  纯文本查看  复制代码
?
 
QConsole.Instance();
就好了,使用之后效果是这样的。


      

    在Editor模式下,F1控制开关。
    在真机上需要在屏幕上同时按下五个手指就可以控制开关了。(本来考虑11个手指萌一下的)。

实现思路:
  1.首先要想办法获取Log,这个和上一篇介绍的QLog一样,需要使用Application.logMessageReceived这个api。
  2.获取到的Log信息要存在一个Queue或者List中,然后把Log输出到屏幕上就ok了。
  3.输出到屏幕上使用的是OnGUI回调和 GUILayout.Window这个api, 总共三步。

贴上代码:
QConsole实现
```
[C#]  纯文本查看  复制代码
?
 
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System.Collections;
using System;
using System.Collections.Generic;
 
namespace QFramework {
         /// <summary>
         /// 控制台GUI输出类
         /// 包括FPS,内存使用情况,日志GUI输出
         /// </summary>
         public class QConsole : QSingleton<QConsole>
         {
 
                 struct ConsoleMessage
                 {
                         public readonly string  message;
                         public readonly string  stackTrace;
                         public readonly LogType        type;
 
                         public ConsoleMessage ( string message, string stackTrace, LogType type)
                         {
                                 this .message    = message;
                                 this .stackTrace        = stackTrace;
                                 this .type       = type;
                         }
                 }
 
                 /// <summary>
                 /// Update回调
                 /// </summary>
                 public delegate void OnUpdateCallback();
                 /// <summary>
                 /// OnGUI回调
                 /// </summary>
                 public delegate void OnGUICallback();
 
                 public OnUpdateCallback onUpdateCallback = null ;
                 public OnGUICallback onGUICallback = null ;
                 /// <summary>
                 /// FPS计数器
                 /// </summary>
                 private QFPSCounter fpsCounter = null ;
                 /// <summary>
                 /// 内存监视器
                 /// </summary>
                 private QMemoryDetector memoryDetector = null ;
                 private bool showGUI = true ;
                 List<ConsoleMessage> entries = new List<ConsoleMessage>();
                 Vector2 scrollPos;
                 bool scrollToBottom = true ;
                 bool collapse;
                 bool mTouching = false ;
 
                 const int margin = 20;
                 Rect windowRect = new Rect(margin + Screen.width * 0.5f, margin, Screen.width * 0.5f - (2 * margin), Screen.height - (2 * margin));
 
                 GUIContent clearLabel    = new GUIContent( "Clear" ,    "Clear the contents of the console." );
                 GUIContent collapseLabel = new GUIContent( "Collapse" , "Hide repeated messages." );
                 GUIContent scrollToBottomLabel = new GUIContent( "ScrollToBottom" , "Scroll bar always at bottom" );
 
 
                 private QConsole()
                 {
                         this .fpsCounter = new QFPSCounter( this );
                         this .memoryDetector = new QMemoryDetector( this );
                         //        this.showGUI = App.Instance().showLogOnGUI;
                         QApp.Instance().onUpdate += Update;
                         QApp.Instance().onGUI += OnGUI;
                         Application.logMessageReceived += HandleLog;
 
                 }
 
                 ~QConsole()
                 {
                         Application.logMessageReceived -= HandleLog;
                 }
                         
 
                 void Update()
                 {
                         #if UNITY_EDITOR
                         if (Input.GetKeyUp(KeyCode.F1))
                                 this .showGUI = ! this .showGUI;
                         #elif UNITY_ANDROID
                         if (Input.GetKeyUp(KeyCode.Escape))
                                 this .showGUI = ! this .showGUI;
                         #elif UNITY_IOS
                         if (!mTouching && Input.touchCount == 4)
                         {
                                 mTouching = true ;
                                 this .showGUI = ! this .showGUI;
                         } else if (Input.touchCount == 0){
                                 mTouching = false ;
                         }
                         #endif
 
                         if ( this .onUpdateCallback != null )
                                 this .onUpdateCallback();
                 }
 
                 void OnGUI()
                 {
                         if (! this .showGUI)
                                 return ;
 
                         if ( this .onGUICallback != null )
                                 this .onGUICallback ();
 
                         if (GUI.Button ( new Rect (100, 100, 200, 100), "清空数据" )) {
                                 PlayerPrefs.DeleteAll ();
                                 #if UNITY_EDITOR
                                 EditorApplication.isPlaying = false ;
                                 #else
                                 Application.Quit();
                                 #endif
                         }
                         windowRect = GUILayout.Window(123456, windowRect, ConsoleWindow, "Console" );
                 }
                         
 
                 /// <summary>
                 /// A window displaying the logged messages.
                 /// </summary>
                 void ConsoleWindow ( int windowID)
                 {
                         if (scrollToBottom) {
                                 GUILayout.BeginScrollView (Vector2.up * entries.Count * 100.0f);
                         }
                         else {
                                 scrollPos = GUILayout.BeginScrollView (scrollPos);
                         }
                         // Go through each logged entry
                         for ( int i = 0; i < entries.Count; i++) {
                                 ConsoleMessage entry = entries[i];[/i]
                                 // If this message is the same as the last one and the collapse feature is chosen, skip it
                                 if (collapse && i > 0 && entry.message == entries[i - 1].message) {
                                         continue ;
                                 }
                                 // Change the text colour according to the log type
                                 switch (entry.type) {
                                         case LogType.Error:
                                         case LogType.Exception:
                                                 GUI.contentColor = Color.red;
                                                 break ;
                                         case LogType.Warning:
                                                 GUI.contentColor = Color.yellow;
                                                 break ;
                                         default :
                                                 GUI.contentColor = Color.white;
                                                 break ;
                                 }
                                 if (entry.type == LogType.Exception)
                                 {
                                         GUILayout.Label(entry.message + " || " + entry.stackTrace);
                                 } else {
                                         GUILayout.Label(entry.message);
                                 }
                         }
                         GUI.contentColor = Color.white;
                         GUILayout.EndScrollView();
                         GUILayout.BeginHorizontal();
                         // Clear button
                         if (GUILayout.Button(clearLabel)) {
                                 entries.Clear();
                         }
                         // Collapse toggle
                         collapse = GUILayout.Toggle(collapse, collapseLabel, GUILayout.ExpandWidth( false ));
                         scrollToBottom = GUILayout.Toggle (scrollToBottom, scrollToBottomLabel, GUILayout.ExpandWidth ( false ));
                         GUILayout.EndHorizontal();
                         // Set the window to be draggable by the top title bar
                         GUI.DragWindow( new Rect(0, 0, 10000, 20));
                 }
 
                 void HandleLog ( string message, string stackTrace, LogType type)
                 {
                         ConsoleMessage entry = new ConsoleMessage(message, stackTrace, type);
                         entries.Add(entry);
                 }
         }
}
QFPSCounter
[C#]  纯文本查看  复制代码
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using UnityEngine;
using System.Collections;
 
namespace QFramework {
         /// <summary>
         /// 帧率计算器
         /// </summary>
         public class QFPSCounter
         {
                 // 帧率计算频率
                 private const float calcRate = 0.5f;
                 // 本次计算频率下帧数
                 private int frameCount = 0;
                 // 频率时长
                 private float rateDuration = 0f;
                 // 显示帧率
                 private int fps = 0;
 
                 public QFPSCounter(QConsole console)
                 {
                         console.onUpdateCallback += Update;
                         console.onGUICallback += OnGUI;
                 }
 
                 void Start()
                 {
                         this .frameCount = 0;
                         this .rateDuration = 0f;
                         this .fps = 0;
                 }
 
                 void Update()
                 {
                         ++ this .frameCount;
                         this .rateDuration += Time.deltaTime;
                         if ( this .rateDuration > calcRate)
                         {
                                 // 计算帧率
                                 this .fps = ( int )( this .frameCount / this .rateDuration);
                                 this .frameCount = 0;
                                 this .rateDuration = 0f;
                         }
                 }
 
                 void OnGUI()
                 {
                         GUI.color = Color.black;
                         GUI.Label( new Rect(80, 20, 120, 20), "fps:" + this .fps.ToString());               
                   }
         }
}
QMemoryDetector
[C#]  纯文本查看  复制代码
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using UnityEngine;[/align] using System.Collections;
 
 
namespace QFramework {
         /// <summary>
         /// 内存检测器,目前只是输出Profiler信息
         /// </summary>
         public class QMemoryDetector
         {
                 private readonly static string TotalAllocMemroyFormation = "Alloc Memory : {0}M" ;
                 private readonly static string TotalReservedMemoryFormation = "Reserved Memory : {0}M" ;
                 private readonly static string TotalUnusedReservedMemoryFormation = "Unused Reserved: {0}M" ;
                 private readonly static string MonoHeapFormation = "Mono Heap : {0}M" ;
                 private readonly static string MonoUsedFormation = "Mono Used : {0}M" ;
                 // 字节到兆
                 private float ByteToM = 0.000001f;
 
                 private Rect allocMemoryRect;
                 private Rect reservedMemoryRect;
                 private Rect unusedReservedMemoryRect;
                 private Rect monoHeapRect;
                 private Rect monoUsedRect;
 
                 private int x = 0;
                 private int y = 0;
                 private int w = 0;
                 private int h = 0;
 
                 public QMemoryDetector(QConsole console)
                 {
                         this .x = 60;
                         this .y = 60;
                         this .w = 200;
                         this .h = 20;
 
                         this .allocMemoryRect = new Rect(x, y, w, h);
                         this .reservedMemoryRect = new Rect(x, y + h, w, h);
                         this .unusedReservedMemoryRect = new Rect(x, y + 2 * h, w, h);
                         this .monoHeapRect = new Rect(x, y + 3 * h, w, h);
                         this .monoUsedRect = new Rect(x, y + 4 * h, w, h);
 
                         console.onGUICallback += OnGUI;
                 }
 
                 void OnGUI()
                 {
                         GUI.Label( this .allocMemoryRect,
                                 string .Format(TotalAllocMemroyFormation, Profiler.GetTotalAllocatedMemory() * ByteToM));
                         GUI.Label( this .reservedMemoryRect,
                                 string .Format(TotalReservedMemoryFormation, Profiler.GetTotalReservedMemory() * ByteToM));
                         GUI.Label( this .unusedReservedMemoryRect,
                                 string .Format(TotalUnusedReservedMemoryFormation, Profiler.GetTotalUnusedReservedMemory() * ByteToM));
                         GUI.Label( this .monoHeapRect,
                                 string .Format(MonoHeapFormation, Profiler.GetMonoHeapSize() * ByteToM));
                         GUI.Label( this .monoUsedRect,
                                 string .Format(MonoUsedFormation, Profiler.GetMonoUsedSize() * ByteToM));
                 }
         }
 
}


注意事项:
    1.和上一篇介绍的QLog一样,需要依赖上上篇文章介绍的QApp。
  2.QConsole初步实现来自于开源Unity-WWW-Wrapper中的Console.cs.在此基础上添加了ScrollToBottom选项。因为这个插件的控制台不支持滚动显示Log,需要拖拽右边的scrollBar,很不方便。
      3.Unity-WWW-wrapper非常不稳定,建议大家不要使用。倒是感兴趣的同学可以研究下实现,贴上地址:https://www.assetstore.unity3d.com/en/#!/content/19116。

欢迎讨论!
附: 我的框架地址: https://github.com/liangxiegame/QFramework
转载请注明地址: 凉鞋的笔记: http://liangxiegame.com/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值