Unity 实现Log实时输出到屏幕或控制台上

第一部分博客链接:

第一部分博客链接

Github 地址: github console window

一、你还是想要一个控制台来显示信息?

为什么呢?这样就不会占用Unity本身的GUI的显示,不去调用Unity的渲染Unity 实现Log实时输出到屏幕或控制台上,转而该为Windows的渲染了。

是不是很惬意Unity 实现Log实时输出到屏幕或控制台上,花费少了,还更灵活了。

好极了。

控制台log文件设置_使用控制台管理自己的文件_制作控制台文件

二、你都需要些什么?

当然是一个控制台窗口和写到控制台的输入了。

代码是歪果仁写的控制台log文件设置,但是很好用。

首先,输入的代码:

名字为ConsoleInput.cs

using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.IO;
namespace ConsoleTestWindows
{
	public class ConsoleInput
	{
		//public delegate void InputText( string strInput );
		public event System.Action OnInputText;
		public string inputString;
		public void ClearLine()
		{
            //System.Text.Encoding test = Console.InputEncoding;
            Console.CursorLeft = 0;
			Console.Write( new String( ' ', Console.BufferWidth ) );
			Console.CursorTop--;
			Console.CursorLeft = 0;
		}
		public void RedrawInputLine()
		{
			if ( inputString.Length == 0 ) return;
			if ( Console.CursorLeft > 0 )
				ClearLine();
			System.Console.ForegroundColor = ConsoleColor.Green;
			System.Console.Write( inputString );
		}
		internal void OnBackspace()
		{
			if ( inputString.Length < 1 ) return;
			inputString = inputString.Substring( 0, inputString.Length - 1 );
			RedrawInputLine();
		}
		internal void OnEscape()
		{
			ClearLine();
			inputString = "";
		}
		internal void OnEnter()
		{
			ClearLine();
			System.Console.ForegroundColor = ConsoleColor.Green;
			System.Console.WriteLine( "> " + inputString );
			var strtext = inputString;
			inputString = "";
			if ( OnInputText != null )
			{
				OnInputText( strtext );
			}
		}
		public void Update()
		{
			if ( !Console.KeyAvailable ) return;
			var key = Console.ReadKey();
			if ( key.Key == ConsoleKey.Enter )
			{
				OnEnter();
				return;
			}
			if ( key.Key == ConsoleKey.Backspace )
			{
				OnBackspace();
				return;
			}
			if ( key.Key == ConsoleKey.Escape )
			{
				OnEscape();
				return;
			}
			if ( key.KeyChar != '\u0000' )
			{
				inputString += key.KeyChar;
				RedrawInputLine();
				return;
			}
		}
	}
}

然后,你还需要一个控制台窗口

如下:

using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.IO;
namespace ConsoleTestWindows
{
	/// 
	/// Creates a console window that actually works in Unity
	/// You should add a script that redirects output using Console.Write to write to it.
	/// 
	public class ConsoleWindow
	{
		TextWriter oldOutput;
		public void Initialize()
		{
			//
			// Attach to any existing consoles we have
			// failing that, create a new one.
			//
			if ( !AttachConsole( 0x0ffffffff ) )
			{
				AllocConsole();
			}
			oldOutput = Console.Out;
			try
			{
				IntPtr stdHandle = GetStdHandle( STD_OUTPUT_HANDLE );
				Microsoft.Win32.SafeHandles.SafeFileHandle safeFileHandle = new Microsoft.Win32.SafeHandles.SafeFileHandle( stdHandle, true );
                FileStream fileStream = new FileStream(safeFileHandle, FileAccess.Write);
				System.Text.Encoding encoding = System.Text.Encoding.ASCII;
				StreamWriter standardOutput = new StreamWriter( fileStream, encoding );
				standardOutput.AutoFlush = true;
				Console.SetOut( standardOutput );
			}
			catch ( System.Exception e )
			{
				Debug.Log( "Couldn't redirect output: " + e.Message );
			}
		}
		public void Shutdown()
		{
			Console.SetOut( oldOutput );
			FreeConsole();
		}
		public void SetTitle( string strName )
		{
			SetConsoleTitle( strName );
		}
		private const int STD_OUTPUT_HANDLE = -11;
		[DllImport( "kernel32.dll", SetLastError = true )]
		static extern bool AttachConsole( uint dwProcessId );
		[DllImport( "kernel32.dll", SetLastError = true )]
		static extern bool AllocConsole();
		[DllImport( "kernel32.dll", SetLastError = true )]
		static extern bool FreeConsole();
		[DllImport( "kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall )]
		private static extern IntPtr GetStdHandle( int nStdHandle );
		[DllImport( "kernel32.dll" )]
		static extern bool SetConsoleTitle( string lpConsoleTitle );
	}
}

三、输入和窗口准备齐全了,问题来了。

当你试图编译代码时候,你会发现居然编译报错,各种找不到。

Console.CursorLeft等大量的方法和变量都找不到。

这是因为Untiy5 默认的目标框架Unity3.5 .net sbu base class Libraries.。在Player Setting中,可设置为.Net 2.0。

控制台log文件设置_使用控制台管理自己的文件_制作控制台文件

制作控制台文件_使用控制台管理自己的文件_控制台log文件设置

这就可以改变了VS下的编译环境了。

但是要是你想要修改编译环境为你想要的其他呢?

四、那么问题来了?怎么修改编译环境的目标框架呢?

使用控制台管理自己的文件_控制台log文件设置_制作控制台文件

你肯定不会是想出这个问题的第一人?所以那就有人来解决问题;

动态的修改你的FrameWork,就可以解答这个问题。

代码:UpgradeVSProject.cs

//#define USE_UPGRADEVS
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
using System.Text.RegularExpressions;
class UpgradeVSProject : AssetPostprocessor
{
#if USE_UPGRADEVS
    private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        string currentDir = Directory.GetCurrentDirectory();
        string[] slnFile = Directory.GetFiles(currentDir, "*.sln");
        string[] csprojFile = Directory.GetFiles(currentDir, "*.csproj");
        bool hasChanged = false;
        if (slnFile != null)
        {
            for (int i = 0; i < slnFile.Length; i++)
            {
                if (ReplaceInFile(slnFile[i], "Format Version 10.00", "Format Version 11.00"))
                    hasChanged = true;
            }
        }
        if (csprojFile != null)
        {
            for (int i = 0; i < csprojFile.Length; i++)
            {
                if (ReplaceInFile(csprojFile[i], "ToolsVersion=\"3.5\"", "ToolsVersion=\"4.0\""))
                    hasChanged = true;
                if (ReplaceInFile(csprojFile[i], "v3.5", "v4.0"))
                    hasChanged = true;
            }
        }
        if (hasChanged)
        {
            Debug.LogWarning("Project is now upgraded to Visual Studio 2010 Solution!");
        }
        else
        {
            Debug.Log("Project-version has not changed...");
        }
    }
    static private bool ReplaceInFile(string filePath, string searchText, string replaceText)
    {
        StreamReader reader = new StreamReader(filePath);
        string content = reader.ReadToEnd();
        reader.Close();
        if (content.IndexOf(searchText) != -1)
        {
            content = Regex.Replace(content, searchText, replaceText);
            StreamWriter writer = new StreamWriter(filePath);
            writer.Write(content);
            writer.Close();
            return true;
        }
        return false;
    }
#endif
}

同样,我写了代码屏蔽的宏定义。使用的时候启用就可以了。

就可以自动升高版本到4.0上控制台log文件设置,当然你也可以修改代码来升高到其他版本的。

注意:这个代码很明显,需要放置在Editor文件夹下。

五、测试结果

我写了个几行的测试代码:

using UnityEngine;
using System.Collections;
public class Tes : MonoBehaviour {
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () 
    {
        if (Input.GetKey(KeyCode.A))
        {
            Debug.Log("this is debug log");
            System.Console.WriteLine("this is system console write line");
        }
	
	}
}

使用控制台管理自己的文件_制作控制台文件_控制台log文件设置

结果就出来了:

制作控制台文件_使用控制台管理自己的文件_控制台log文件设置

别告诉我,这不是你想要的控制台窗口。

你看看,在写Log时,会不会造成你的游戏卡顿了呢??

---------THE END------------------------

若有问题,请随时联系!

非常感谢!!

标签:   Log 实时输出   屏幕   控制台   VS 编译环境

留言评论