zoukankan      html  css  js  c++  java
  • Unity 实现Log实时输出到屏幕或控制台上<二>

    本文章由cartzhang编写,转载请注明出处。 所有权利保留。 

    文章链接:http://blog.csdn.net/cartzhang/article/details/49884507

    作者:cartzhang



    第一部分博客链接: http://blog.csdn.net/cartzhang/article/details/49818953

    第一部分博客链接


    Github 地址:https://github.com/cartzhang/TestConsoleWindow  github console window



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

        为什么呢?这样就不会占用Unity本身的GUI的显示,不去调用Unity的渲染,转而该为Windows的渲染了。

    是不是很惬意,花费少了,还更灵活了。


    好极了。

    二、你都需要些什么?

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

    代码是歪果仁写的,但是很好用。

    首先,输入的代码:
    名字为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<string> 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
    {
    	/// <summary>
    	/// Creates a console window that actually works in Unity
    	/// You should add a script that redirects output using Console.Write to write to it.
    	/// </summary>
    	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。


    这就可以改变了VS下的编译环境了。
    但是要是你想要修改编译环境为你想要的其他呢?

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



    你肯定不会是想出这个问题的第一人?所以那就有人来解决问题;
    动态的修改你的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], "<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>", "<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>"))
                        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上,当然你也可以修改代码来升高到其他版本的。

    注意:这个代码很明显,需要放置在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时,会不会造成你的游戏卡顿了呢??

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

    若有问题,请随时联系!
    非常感谢!!




  • 相关阅读:
    Alook搭配JS脚本完美食用
    分享小米刷机教程/线刷(工具支持小米华为一加)
    iPhone 无需越狱修改wx+zfb+qq步数
    如果SELECT语句中没有结果,则使用CASE返回字符串
    MSSQLServer 正在显示"正在还原...."
    C# 小技巧
    C#使用Select方法快速获取List集合集合中某个属性的所有值集合
    C#中使用Sum方法对List集合进行求和操作
    sql日期函数
    sql只根据某一字段去重,并保留其他字段
  • 原文地址:https://www.cnblogs.com/qitian1/p/6461937.html
Copyright © 2011-2022 走看看