Unity 实现Log实时输出到屏幕或控制台上<一>
本文章由cartzhang编写,转载请注明出处。 所有权利保留。
文章链接:http://blog.csdn.net/cartzhang/article/details/49818953
作者:cartzhang
一、Unity 打印日志
Unity中,在其编辑器上有个专门的Console,快捷键:shift + Ctrl+ c 。
代码中的Debug.Log("this is a test");就会打印到这里。
但是在打包后,只有从Log中找到,能不能找到一个可以实时显示的工具呢?
很明显,必须有啊!!要不写这篇不就是瞎扯了么?!!
我辗转腾挪,到处寻觅,我肯定不是第一个有这个想法的人。
终于有一天,我来到了七环!!!找到了几种方法,与君共享!!
二、我想有个控制台
之前说的Debug.Log();此函数是打印Unity控制台的。
好办,有高人已经重新把控制台给换了地方,打印到界面的控制台上。
就是类似控制台的一个界面。
先放结果图样:
1.问题来了,怎么实现的呢?
上代码:
我给改了名字叫TestConsole.cs了,因为之前名字为Console,这样想我这样都在一个工程中为大家测试,容易造成混乱。
//#define USE_TESTCONSOLE
using System.Collections.Generic;
using UnityEngine; namespace Consolation
{
/// <summary>
/// A console to display Unity's debug logs in-game.
/// </summary>
class TestConsole : MonoBehaviour
{
#if USE_TESTCONSOLE
struct Log
{
public string message;
public string stackTrace;
public LogType type;
} #region Inspector Settings /// <summary>
/// The hotkey to show and hide the console window.
/// </summary>
public KeyCode toggleKey = KeyCode.BackQuote; /// <summary>
/// Whether to open the window by shaking the device (mobile-only).
/// </summary>
public bool shakeToOpen = true; /// <summary>
/// The (squared) acceleration above which the window should open.
/// </summary>
public float shakeAcceleration = 3f; /// <summary>
/// Whether to only keep a certain number of logs.
///
/// Setting this can be helpful if memory usage is a concern.
/// </summary>
public bool restrictLogCount = false; /// <summary>
/// Number of logs to keep before removing old ones.
/// </summary>
public int maxLogs = 1000; #endregion readonly List<Log> logs = new List<Log>();
Vector2 scrollPosition;
bool visible;
bool collapse; // Visual elements: static readonly Dictionary<LogType, Color> logTypeColors = new Dictionary<LogType, Color>
{
{ LogType.Assert, Color.white },
{ LogType.Error, Color.red },
{ LogType.Exception, Color.red },
{ LogType.Log, Color.white },
{ LogType.Warning, Color.yellow },
}; const string windowTitle = "Console";
const int margin = 20;
static readonly GUIContent clearLabel = new GUIContent("Clear", "Clear the contents of the console.");
static readonly GUIContent collapseLabel = new GUIContent("Collapse", "Hide repeated messages."); readonly Rect titleBarRect = new Rect(0, 0, 10000, 20);
Rect windowRect = new Rect(margin, margin, Screen.width - (margin * 2), Screen.height - (margin * 2)); void OnEnable()
{
#if UNITY_5
Application.logMessageReceived += HandleLog;
#else
Application.RegisterLogCallback(HandleLog);
#endif
} void OnDisable()
{
#if UNITY_5
Application.logMessageReceived -= HandleLog;
#else
Application.RegisterLogCallback(null);
#endif
} void Update()
{
if (Input.GetKeyDown(toggleKey))
{
visible = !visible;
} if (shakeToOpen && Input.acceleration.sqrMagnitude > shakeAcceleration)
{
visible = true;
}
} void OnGUI()
{
if (!visible)
{
return;
} windowRect = GUILayout.Window(123456, windowRect, DrawConsoleWindow, windowTitle);
} /// <summary>
/// Displays a window that lists the recorded logs.
/// </summary>
/// <param name="windowID">Window ID.</param>
void DrawConsoleWindow(int windowID)
{
DrawLogsList();
DrawToolbar(); // Allow the window to be dragged by its title bar.
GUI.DragWindow(titleBarRect);
} /// <summary>
/// Displays a scrollable list of logs.
/// </summary>
void DrawLogsList()
{
scrollPosition = GUILayout.BeginScrollView(scrollPosition); // Iterate through the recorded logs.
for (var i = 0; i < logs.Count; i++)
{
var log = logs[i]; // Combine identical messages if collapse option is chosen.
if (collapse && i > 0)
{
var previousMessage = logs[i - 1].message; if (log.message == previousMessage)
{
continue;
}
} GUI.contentColor = logTypeColors[log.type];
GUILayout.Label(log.message);
} GUILayout.EndScrollView(); // Ensure GUI colour is reset before drawing other components.
GUI.contentColor = Color.white;
} /// <summary>
/// Displays options for filtering and changing the logs list.
/// </summary>
void DrawToolbar()
{
GUILayout.BeginHorizontal(); if (GUILayout.Button(clearLabel))
{
logs.Clear();
} collapse = GUILayout.Toggle(collapse, collapseLabel, GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal();
} /// <summary>
/// Records a log from the log callback.
/// </summary>
/// <param name="message">Message.</param>
/// <param name="stackTrace">Trace of where the message came from.</param>
/// <param name="type">Type of message (error, exception, warning, assert).</param>
void HandleLog(string message, string stackTrace, LogType type)
{
logs.Add(new Log
{
message = message,
stackTrace = stackTrace,
type = type,
}); TrimExcessLogs();
} /// <summary>
/// Removes old logs that exceed the maximum number allowed.
/// </summary>
void TrimExcessLogs()
{
if (!restrictLogCount)
{
return;
} var amountToRemove = Mathf.Max(logs.Count - maxLogs, 0); if (amountToRemove == 0)
{
return;
} logs.RemoveRange(0, amountToRemove);
}
#endif
}
}
我在代码最前面添加了宏定义,使用的时候屏蔽此宏定义即可。
2.怎么使用呢?
// Update is called once per frame
void Update ()
{
//DebugConsole.Log(" test s");
Debug.Log("Debug log test");
Console.WriteLine("this is Console Write line test ");
///
//DebugConsole.instance.AddMessage("this is instance AddMessage test by cartzhang", "warning");
//DebugConsole.Log("this is debug console log test cartzhang");
}
3.结果上面已经说明了。
4.这怎么实现的呢?
三、这不是我想要的,我要显示在屏幕上。
1. 直接写在屏幕上的代码
/*==== DebugConsole.cs ====================================================
* Class for handling multi-line, multi-color debugging messages.
* Original Author: Jeremy Hollingsworth
* Based On: Version 1.2.1 Mar 02, 2006
*
* Modified: Simon Waite
* Date: 22 Feb 2007
*
* Modification to original script to allow pixel-correct line spacing
*
* Setting the boolean pixelCorrect changes the units in lineSpacing property
* to pixels, so you have a pixel correct gui font in your console.
*
* It also checks every frame if the screen is resized to make sure the
* line spacing is correct (To see this; drag and let go in the editor
* and the text spacing will snap back)
*
* USAGE:
* ::Drop in your standard assets folder (if you want to change any of the
* default settings in the inspector, create an empty GameObject and attach
* this script to it from you standard assets folder. That will provide
* access to the default settings in the inspector)
*
* ::To use, call DebugConsole.functionOrProperty() where
* functionOrProperty = one of the following:
*
* -Log(string message, string color) Adds "message" to the list with the
* "color" color. Color is optional and can be any of the following: "error",
* "warning", or "normal". Default is normal.
*
* Clear() Clears all messages
*
* isVisible (true,false) Toggles the visibility of the output. Does _not_
* clear the messages.
*
* isDraggable (true, false) Toggles mouse drag functionality
* =========================================================================*/
//#define USE_DEBUGCONSOLE using UnityEngine;
using System.Collections; public class DebugConsole : MonoBehaviour
{
#if USE_DEBUGCONSOLE
public GameObject DebugGui = null; // The GUI that will be duplicated
public Vector3 defaultGuiPosition = new Vector3(0.01F, 0.98F, 0F);
public Vector3 defaultGuiScale = new Vector3(0.5F, 0.5F, 1F);
public Color normal = Color.green;
public Color warning = Color.yellow;
public Color error = Color.red;
public int maxMessages = 30; // The max number of messages displayed
public float lineSpacing = 0.02F; // The amount of space between lines
public ArrayList messages = new ArrayList();
public ArrayList guis = new ArrayList();
public ArrayList colors = new ArrayList();
public bool draggable = true; // Can the output be dragged around at runtime by default?
public bool visible = true; // Does output show on screen by default or do we have to enable it with code?
public bool pixelCorrect = false; // set to be pixel Correct linespacing
public static bool isVisible
{
get
{
return DebugConsole.instance.visible;
} set
{
DebugConsole.instance.visible = value;
if (value == true)
{
DebugConsole.instance.Display();
}
else if (value == false)
{
DebugConsole.instance.ClearScreen();
}
}
} public static bool isDraggable
{
get
{
return DebugConsole.instance.draggable;
} set
{
DebugConsole.instance.draggable = value; }
} private static DebugConsole s_Instance = null; // Our instance to allow this script to be called without a direct connection.
public static DebugConsole instance
{
get
{
if (s_Instance == null)
{
s_Instance = FindObjectOfType(typeof(DebugConsole)) as DebugConsole;
if (s_Instance == null)
{
GameObject console = new GameObject();
console.AddComponent<DebugConsole>();
console.name = "DebugConsoleController";
s_Instance = FindObjectOfType(typeof(DebugConsole)) as DebugConsole;
DebugConsole.instance.InitGuis();
} } return s_Instance;
}
} void Awake()
{
s_Instance = this;
InitGuis(); } protected bool guisCreated = false;
protected float screenHeight =-1;
public void InitGuis()
{
float usedLineSpacing = lineSpacing;
screenHeight = Screen.height;
if(pixelCorrect)
usedLineSpacing = 1.0F / screenHeight * usedLineSpacing; if (guisCreated == false)
{
if (DebugGui == null) // If an external GUIText is not set, provide the default GUIText
{
DebugGui = new GameObject();
DebugGui.AddComponent<GUIText>();
DebugGui.name = "DebugGUI(0)";
DebugGui.transform.position = defaultGuiPosition;
DebugGui.transform.localScale = defaultGuiScale;
} // Create our GUI objects to our maxMessages count
Vector3 position = DebugGui.transform.position;
guis.Add(DebugGui);
int x = 1; while (x < maxMessages)
{
position.y -= usedLineSpacing;
GameObject clone = null;
clone = (GameObject)Instantiate(DebugGui, position, transform.rotation);
clone.name = string.Format("DebugGUI({0})", x);
guis.Add(clone);
position = clone.transform.position;
x += 1;
} x = 0;
while (x < guis.Count)
{
GameObject temp = (GameObject)guis[x];
temp.transform.parent = DebugGui.transform;
x++;
}
guisCreated = true;
} else {
// we're called on a screensize change, so fiddle with sizes
Vector3 position = DebugGui.transform.position;
for(int x=0;x < guis.Count; x++)
{
position.y -= usedLineSpacing;
GameObject temp = (GameObject)guis[x];
temp.transform.position= position;
}
}
} bool connectedToMouse = false;
void Update()
{
// If we are visible and the screenHeight has changed, reset linespacing
if (visible == true && screenHeight != Screen.height)
{
InitGuis();
}
if (draggable == true)
{
if (Input.GetMouseButtonDown(0))
{
if (connectedToMouse == false && DebugGui.GetComponent<GUIText>().HitTest((Vector3)Input.mousePosition) == true)
{
connectedToMouse = true;
}
else if (connectedToMouse == true)
{
connectedToMouse = false;
} } if (connectedToMouse == true)
{
float posX = DebugGui.transform.position.x;
float posY = DebugGui.transform.position.y;
posX = Input.mousePosition.x / Screen.width;
posY = Input.mousePosition.y / Screen.height;
DebugGui.transform.position = new Vector3(posX, posY, 0F);
}
} }
//+++++++++ INTERFACE FUNCTIONS ++++++++++++++++++++++++++++++++
public static void Log(string message, string color)
{
DebugConsole.instance.AddMessage(message, color); }
//++++ OVERLOAD ++++
public static void Log(string message)
{
DebugConsole.instance.AddMessage(message);
} public static void Clear()
{
DebugConsole.instance.ClearMessages();
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //---------- void AddMesage(string message, string color) ------
//Adds a mesage to the list
//-------------------------------------------------------------- public void AddMessage(string message, string color)
{
messages.Add(message);
colors.Add(color);
Display();
}
//++++++++++ OVERLOAD for AddMessage ++++++++++++++++++++++++++++
// Overloads AddMessage to only require one argument(message)
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public void AddMessage(string message)
{
messages.Add(message);
colors.Add("normal");
Display();
} //----------- void ClearMessages() ------------------------------
// Clears the messages from the screen and the lists
//---------------------------------------------------------------
public void ClearMessages()
{
messages.Clear();
colors.Clear();
ClearScreen();
} //-------- void ClearScreen() ----------------------------------
// Clears all output from all GUI objects
//--------------------------------------------------------------
void ClearScreen()
{
if (guis.Count < maxMessages)
{
//do nothing as we haven't created our guis yet
}
else
{
int x = 0;
while (x < guis.Count)
{
GameObject gui = (GameObject)guis[x];
gui.GetComponent<GUIText>().text = "";
//increment and loop
x += 1;
}
}
} //---------- void Prune() ---------------------------------------
// Prunes the array to fit within the maxMessages limit
//---------------------------------------------------------------
void Prune()
{
int diff;
if (messages.Count > maxMessages)
{
if (messages.Count <= 0)
{
diff = 0;
}
else
{
diff = messages.Count - maxMessages;
}
messages.RemoveRange(0, (int)diff);
colors.RemoveRange(0, (int)diff);
} } //---------- void Display() -------------------------------------
// Displays the list and handles coloring
//---------------------------------------------------------------
void Display()
{
//check if we are set to display
if (visible == false)
{
ClearScreen();
}
else if (visible == true)
{ if (messages.Count > maxMessages)
{
Prune();
} // Carry on with display
int x = 0;
if (guis.Count < maxMessages)
{
//do nothing as we havent created our guis yet
}
else
{
while (x < messages.Count)
{
GameObject gui = (GameObject)guis[x]; //set our color
switch ((string)colors[x])
{
case "normal": gui.GetComponent<GUIText>().material.color = normal;
break;
case "warning": gui.GetComponent<GUIText>().material.color = warning;
break;
case "error": gui.GetComponent<GUIText>().material.color = error;
break;
} //now set the text for this element
gui.GetComponent<GUIText>().text = (string)messages[x]; //increment and loop
x += 1;
}
} }
}
#endif }// End DebugConsole Class
2.使用方法
//DebugConsole.instance.AddMessage("this is instance AddMessage test by cartzhang", "warning");
//DebugConsole.Log("this is debug console log test cartzhang");
3.结果如图
四、这还不是我想要的,我要显示在控制台上,就是CMD出来的那样。
Unity 实现Log实时输出到屏幕或控制台上<一>的更多相关文章
- Unity 实现Log实时输出到屏幕或控制台上<二>
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/49884507 作者:car ...
- unity收集log工具
参考 yusong:http://www.xuanyusong.com/archives/2477 凉鞋 :https://www.cnblogs.com/liangxiegame/p/Uni ...
- [Linux]屏幕输出控制
专门的术语叫做ANSI Escape sequences(ANSI Escape codes),题目并不恰当,与其说是屏幕输出控制,不如说是通过bash在兼容VT100的终端上进行输出. 主要有以下类 ...
- .NET Core下的日志(3):如何将日志消息输出到控制台上
当我们利用LoggerFactory创建一个Logger对象并利用它来实现日志记录,这个过程会产生一个日志消息,日志消息的流向取决于注册到LoggerFactory之上的LoggerProvider. ...
- java 在控制台上输入密码时,密码不显示在控制台上
用下面的方法可以实现在控制台上输入密码时,密码不显示在控制台上:Console cons=System.console(); System.out.print(" 密码:"); c ...
- 大数据调错系列之hadoop在开发工具控制台上打印不出日志的解决方法
(1)在windows环境上配置HADOOP_HOME环境变量 (2)在eclipse上运行程序 (3)注意:如果eclipse打印不出日志,在控制台上只显示 1.log4j:WARN No appe ...
- eclipse:eclipse for java EE环境下如何配置tomcat服务器,并让tomcat服务器显示在控制台上,将Web应用部署到tomcat中
eclipse环境下如何配置tomcat 打开Eclipse,单击"Window"菜单,选择下方的"Preferences". 单击"Server& ...
- Ubuntu上运行Blender,在控制台上查看运行结果
1.首先在控制台打开Blender. 具体操作:找到Blender的安装路径,我的是:/home/lcx/下载/blender-2.78c-linux-glibc219-x86_64 $cd /hom ...
- Java:IO流的综合用法(从键盘录入数据并打印在控制台上)
import java.io.*; public class IOTestDouble { public static void main(String[] args)throws Exception ...
随机推荐
- C#获取本机内网外网IP
using System.Net; # region 获取内.外网Ip /// <summary> /// 获取本地ip地址,优先取内网ip /// </summary> pu ...
- Dynamics CRM2013 Form利用window.location.reload()进行全局刷新带来的问题及解决的方法
CRM2013以后.表单的保存后变成了局部刷新而非全局刷新,但非常多情况下我们须要刷新整个页面.通过刷新页面来使脚本运行或者业务规则运行来实现某些业务效果,一般我们会使用window.location ...
- new 对象和Class的getInstance()方法的差别?
创建对象时的差别 1.new 对象包含2步, 1)载入类: 2)而且实例化. 2.Class的对象.getInstance(),只不过实例化. 也就是说.在运行 Class的对象.getInstanc ...
- Android Shape使用
说明 在Android开发中,使用shape可以很方便的帮我们画出想要的背景,相对于png图片来说,使用shape可以减少安装包的大小,而且能够更好的适配不同的手机. 使用 先贴出官网上的说明: &l ...
- Python: PS 滤镜--碎片特效
本文用 Python 实现 PS 滤镜中的碎片特效,这个特效简单来说就是将图像在 上,下,左,右 四个方向做平移,然后将四个方向的平移的图像叠加起来做平均.具体的效果图可以参考之前的博客 http:/ ...
- LBP(Local Binary Patterns)局部二进制模式
1. LBP 用于人脸识别 为了预测每个像素属于哪个脸部器官(眼睛.鼻子.嘴.头发),通常的作法是在该像素周围取一个小的区域,提取纹理特征(例如局部二值模式),再基于该特征利用支持向量机等浅层模型分类 ...
- 45.angular路由设置
转自:https://www.cnblogs.com/best/tag/Angular/ AngularJS 路由也可以通过不同的模板来实现. $routeProvider.when 函数的第一个参数 ...
- 13.mutiset树每一个结点都是一个链表的指针,可以存储相同的数据
#include <iostream> //红黑树(自动保证平衡,自动生成平衡查找树) #include <set> #include <cstring> #inc ...
- idea报错。Error:Failed to load project configuration: cannot parse xml file E:\project\.idea\workspace.xml: Error on line 1: 前言中不允许有内容。
因为电脑卡死强制重启电脑后打开idea,进行junit单元测试报错: idea报错.Error:Failed to load project configuration: cannot parse x ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)
题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...