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

为毛要实现这个工具?

  1. 在我小时候,每当游戏在真机运行时,我们看到的日志是这样的。 没高亮啊,还有乱七八糟的堆栈信息,好干扰日志查看,好影响心情。
  1. 还有就是必须始终连着 usb 线啊,我想要想躺着测试。。。 以上种种原因,QConsole 诞生了。

如何使用?

使用方式和QLog一样,在初始化出调用,简单的一句。

    
QConsole . Instance ( ) ;
就好了,使用之后效果是这样的。 在 Editor 模式下,F1控制开关。
在真机上需要在屏幕上同时按下五个手指就可以控制开关了。(本来考虑 11 个手指萌一下的)。

实现思路:

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

贴上代码:

QConsole实现

    
sing 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 ] ; // 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

    
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

    
using UnityEngine ; 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 插件 Unity-WWW-Wrapper 中的 Console.cs.在此基础上添加了 ScrollToBottom 选项。因为这个插件的控制台不支持滚动显示 Log,需要拖拽右边的 scrollBar,很不方便。
  3. Unity-WWW-wrapper 非常不稳定,建议大家不要使用。倒是感兴趣的同学可以研究下实现,贴上地址:https://www.assetstore.unity3d.com/en/#!/content/19116。转载请注明地址:凉鞋的笔记: liangxiegame.com

欢迎讨论!

更多内容

  • QQ 交流群: 623597263
  • Unity 进阶小班 :
  • 主要训练内容:
  • 框架搭建训练(第一年)
  • 跟着案例学 Shader(第一年)
  • 副业的孵化(第二年、第三年)
  • 权益、授课形式等具体详情请查看 《小班产品手册》 :https://liangxiegame.com/master/intro
  • 关注公众号:liangxiegame 获取第一时间更新通知及更多的免费内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值