自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

时间:2024-03-15 20:27:56

刚刚入坑Unity时,还没什么感觉,用久了Unity自带的日志系统,有时候全屏化后看日志是真的麻烦,于是就产生了自己写一个Pro版的想法,可能有些不完善,勤劳的小伙伴可以再去升级。下面开始动手。

 

因为Unity的一些机制,我们需要把我们的工具以DLL的形式调用。具体原因是因为不封装成DLL的话,进行打印追踪时会直接追踪到我们的工具内部,而不是调用工具打印的那个位置。

 

新建一个C#类库工程  我用的是vs2017  其他版本差不多 .net框架版本选择3.5的试了好几次

自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

然后你会得到这样的一个工程

自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

 

然后去引用UnityEngine.dll  具体目录为xxxx\Unity\Editor\Data\Managed\UnityEngine.dll

自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

 

然后代码复制过去

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Blm{
	public enum ShowStats{
		ShowNormalLogOnly,
		ShowErrorOnly,
		ShowImportantLog,
		ShowAllLog
	}
	public class Log :MonoBehaviour{
		static public Texture Logimage, Errorimage, p3;
		static public bool IsBackgroundOutput = true;//是否后台输出
		static public int Mutll = 1;//高度倍数
		static public float ScrollCurryPlan;//当前垂直方向滑动高度
		static public int MaxCacheCount = 100;//Log缓存条数
		static public bool IsShowGUILog = true;//是否显示GUILog
		static public Vector2 scrollPosition = Vector2.zero;//滑动条滑动量X > 水平  Y > 垂直
		static public Rect rect = new Rect(0,0,300,Screen.height - 100);//窗口信息(位置与大小)
		static public bool IsShowWindow = false,IsShowHintButton = true;//是否显示窗口 是否显示按钮
		static public List<string> LabelStrList = new List<string> ();//保存Log的List
		static public bool IsStop = false;//是否继续输出
		static public float Logwh = 25;//按钮图标的大小
		static public Color NormalLogColor = Color.white,ErrorrLogColor = Color.red,ImportanLogColor = Color.cyan;
		public ShowStats showStats;//
		static public Log User;
		public void Start(){
			if (User == null) {
				User = this;
			}
			showStats = ShowStats.ShowAllLog;
			ScrollCurryPlan = Screen.height;
		}
		private void FixedUpdate(){
			IsShowHintButton = !IsShowWindow;
			if(Input.GetKey(KeyCode.LeftControl)){
				if(Input.GetKeyUp(KeyCode.L)){
					IsShowGUILog = !IsShowGUILog;
				}
			}
		}

//		static public void Main(string[] args){
//			
//		}
		private void OnGUI(){
			if (!IsShowGUILog)
				return;
			if(IsShowHintButton){
				if(GUI.Button(new Rect(Screen.width / 2 - 100,5,200,40),"显示信息面板")){
					IsShowWindow = !IsShowWindow;
					IsShowHintButton = false;
				}
			}
			if(IsShowWindow){
				GUILayout.Window (0,rect, GUIWindow, "BlmLog");
			}
		}


		private void GUIWindow(int wID){
			if(MaxCacheCount < LabelStrList.Count){
				LabelStrList.Remove (LabelStrList[0]);
			}
			GUILayout.BeginHorizontal ();
			if (GUILayout.Button ("清除")) {
				LabelStrList.Clear ();
			}
			if (IsStop) {
				GUI.color = ErrorrLogColor;
				if (GUILayout.Button ("暂停:" + IsStop.ToString ())) {
					IsStop = !IsStop;
				}
				GUI.color = NormalLogColor;
			} else {
				GUI.color = NormalLogColor;
				if (GUILayout.Button ("暂停:" + IsStop.ToString ())) {
					IsStop = !IsStop;
				}
			}
			if (GUILayout.Button ("关闭")) {
				IsShowHintButton = true;
				IsShowWindow = false;
			}
			GUILayout.EndHorizontal ();
			GUILayout.BeginHorizontal ();
			if (GUILayout.Button (Logimage,GUILayout.Width(Logwh),GUILayout.Height(Logwh))) {
				showStats = ShowStats.ShowNormalLogOnly;
			}
			GUI.color = ErrorrLogColor;
			if (GUILayout.Button (Errorimage,GUILayout.Width(Logwh),GUILayout.Height(Logwh))) {
				showStats = ShowStats.ShowErrorOnly;
			}
			GUI.color = NormalLogColor;
			if (GUILayout.Button ("AllLog",GUILayout.Height(Logwh))) {
				showStats = ShowStats.ShowAllLog;
			}
			GUILayout.EndHorizontal ();

			//开始滚动布局
			scrollPosition = GUILayout.BeginScrollView (scrollPosition, GUILayout.Height (rect.height));
			for(int i = 0; i < LabelStrList.Count; i++){
				try{
					switch(LabelStrList[i].Split(':')[0]){
					case "Error":
						if(showStats != ShowStats.ShowErrorOnly && showStats != ShowStats.ShowAllLog)
							continue;
						GUI.color = ErrorrLogColor;
						GUILayout.BeginHorizontal ();
						GUILayout.Box (i.ToString (),GUILayout.Width(50));
						GUILayout.TextArea (LabelStrList[i].Substring(LabelStrList[i].IndexOf(':')+1));  
						GUILayout.EndHorizontal ();
						GUI.color = NormalLogColor;
						break;
					case "Log":
						if(showStats != ShowStats.ShowNormalLogOnly && showStats != ShowStats.ShowAllLog)
							continue;
						GUI.color = NormalLogColor;
						GUILayout.BeginHorizontal ();
						GUILayout.Box (i.ToString (),GUILayout.Width(50));
						GUILayout.TextArea (LabelStrList[i].Substring(LabelStrList[i].IndexOf(':')+1));  
						GUILayout.EndHorizontal ();
						GUI.color = NormalLogColor;
						break;
					case "Important":
						GUI.color = ImportanLogColor;
						GUILayout.BeginHorizontal ();
						GUILayout.Box (i.ToString (),GUILayout.Width(50));
						GUILayout.TextArea (LabelStrList[i].Substring(LabelStrList[i].IndexOf(':')+1));  
						GUILayout.EndHorizontal ();
						GUI.color = NormalLogColor;
						break;
					default:
						GUI.color = ErrorrLogColor;
						GUILayout.BeginHorizontal ();
						GUILayout.Box (i.ToString (),GUILayout.Width(50));
						GUILayout.TextArea (LabelStrList[i].Substring(LabelStrList[i].IndexOf(':')+1));  
						GUILayout.EndHorizontal ();
						GUI.color = NormalLogColor;
						break;
					}
				}catch(System.Exception ex){
					GUI.color = NormalLogColor;
					GUILayout.TextArea ("Log打印出错!\n错误信息:"+ex.Message);
					GUI.color = NormalLogColor;
				}
			}
			//结束滚动布局
			GUILayout.EndScrollView ();
			GUILayout.Label ("当前显示状态:"+showStats.ToString());
		}


		static public void Show(object obj){
			if (IsStop)
				return;
			if(IsBackgroundOutput){
				Debug.Log (obj.ToString());
			}
			LabelStrList.Add ("Log:" + obj.ToString());
			UpdateScrollPlan ();
		}

		static public void ShowError(object obj){
			if (IsStop)
				return;
			if(IsBackgroundOutput){
				Debug.LogError (obj.ToString());
			}
			LabelStrList.Add ("Error:" + obj.ToString());
			UpdateScrollPlan ();
		}

		static public void ShowImportant(object obj){
			if (IsStop)
				return;
			Debug.Log (obj.ToString());
			LabelStrList.Add ("Important:" + obj.ToString());
			UpdateScrollPlan ();
		}

		/// <summary>
		/// 刷新滑动面板的进度到底部
		/// </summary>
		static public void UpdateScrollPlan(){
			if (scrollPosition.y < ScrollCurryPlan) {
				scrollPosition = new Vector2 (0, ScrollCurryPlan);
			} else {
				scrollPosition = new Vector2(0,++Mutll * ScrollCurryPlan) ;
			}
		}

	}
}

修改项目属性项目为

自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

生成解决方案即可

自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

 

新建Unity工程测试一下

在Unity工程下创建Plugins文件夹,然后将刚刚生成的DLL放进去

自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

 

然后编写辅助脚本(实例化Log对象)自己看着弄哈

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Blm;
public class BlmLog : MonoBehaviour {
	public Texture p1, p2, p3;
	private void Awake () {
		if(Log.User == null){
			GameObject log = new GameObject ("MyLog");
			log.AddComponent<Log> ();
			DontDestroyOnLoad (log);
		}
		Log.IsStop = false;//是否暂停
		Log.IsShowWindow = true;//是否直接显示窗口
		Log.IsBackgroundOutput = false;//是否后台输出
		Log.Logimage = this.p1;//常规Log图标
		Log.Errorimage = this.p2;//错误Log图标 
		Log.rect = new Rect(Screen.width/2 - (Screen.width/2)/2,10,Screen.width/2,Screen.height - Screen.height / 3);//窗口位置与大小
		//。。。
	}
}

把脚本挂到随便一个对象上运行

自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

Test测试脚本

using System.Collections;
using System.Collections.Generic;
using Blm;
using UnityEngine;

public class Test : MonoBehaviour {

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        if (Input.GetMouseButtonUp(0))//鼠标左击触发
        {
            Log.Show("日志1");
        }
        if (Input.GetMouseButtonUp(1))
        {
            Log.ShowError("日志2");
        }
        if (Input.GetMouseButtonUp(2))
        {
            Log.ShowImportant("日志3");
        }
    }
}

自己动手编写Unity基于GUI的日志系统,直接绘制在界面上,很直观

 

成品下载:点这里

OVER!