本文章由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------------------------
若有问题,请随时联系!
非常感谢!!