💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
本文章由cartzhang编写,转载请注明出处。 所有权利保留。  文章链接:http://blog.csdn.net/cartzhang/article/details/49884507 作者:cartzhang 第一部分博客链接: http://blog.csdn.net/cartzhang/article/details/49818953 [第一部分博客链接](http://blog.csdn.net/cartzhang/article/details/49818953) Github 地址:https://github.com/cartzhang/TestConsoleWindow  [github console window](https://github.com/cartzhang/TestConsoleWindow) ### 一、你还是想要一个控制台来显示信息? 为什么呢?这样就不会占用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。 ![](https://box.kancloud.cn/2016-03-09_56dfda863241b.jpg) 这就可以改变了VS下的编译环境了。 但是要是你想要修改编译环境为你想要的其他呢? ### 四、那么问题来了?怎么修改编译环境的目标框架呢? ![](https://box.kancloud.cn/2016-03-09_56dfda8642948.jpg) 你肯定不会是想出这个问题的第一人?所以那就有人来解决问题; 动态的修改你的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"); } } } ~~~ 结果就出来了: ![](https://box.kancloud.cn/2016-03-09_56dfda8656f48.jpg) 别告诉我,这不是你想要的控制台窗口。 你看看,在写Log时,会不会造成你的游戏卡顿了呢?? ---------THE END------------------------ 若有问题,请随时联系! 非常感谢!!