一、你还是想要一个控制台来显示信息?
前面介绍了实现Log实时输出到屏幕,但是还需要一个控制台来显示信息,为什么呢?这样就不会占用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 event System.Action<string> OnInputText;
- public string inputString;
-
- public void ClearLine()
- {
-
- 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
- {
-
-
-
-
- public class ConsoleWindow
- {
- TextWriter oldOutput;
-
- public void Initialize()
- {
-
-
-
-
- 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
-
- 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 {
-
-
- void Start () {
-
- }
-
-
- void Update ()
- {
- if (Input.GetKey(KeyCode.A))
- {
- Debug.Log("this is debug log");
- System.Console.WriteLine("this is system console write line");
- }
-
- }
- }
结果就出来了:
别告诉我,这不是你想要的控制台窗口。
你看看,在写Log时,会不会造成你的游戏卡顿了呢??