- 最后登录
- 2016-8-29
- 注册时间
- 2012-8-25
- 阅读权限
- 90
- 积分
- 23585
- 纳金币
- 20645
- 精华
- 62
|
转自 : 杰杰猫
写了一个unity3d的Debug Console类,可以通过命令字符串调用相应的函数,方便测试和调试,但还没写UI,大家自己去实现吧。
在Unity商店里有类似功能的插件Easyconsole,卖25$,觉得太贵了,就自己实现了一个。
DebugConsole.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
static public class DebugConsole
{
class Command {
public readonly string CommandName;
public readonly string FuncName;
public readonly Object Callee;
public Command(string cmdName, Object callee, string funcName) {
CommandName = cmdName;
FuncName = funcName;
Callee = callee;
}
}
static private Dictionary<string, Command> mCmdLst;
static DebugConsole() {
mCmdLst = new Dictionary<string, Command>();
}
static public void RegisterCommand(string cmdName, Object callee, string funcName) {
if (mCmdLst == null)
mCmdLst = new Dictionary<string, Command>();
Command cmd = new Command(cmdName, callee, funcName);
if(!mCmdLst.ContainsKey(cmdName)) {
mCmdLst.Add(cmdName, cmd);
}
}
static public bool Execute(string cmdStr) {
string[] argv = ParseArguments(cmdStr);
Command cmd = mCmdLst[argv[0]];
if (cmd == null) {
return false;
}
// get method
MethodInfo method = cmd.Callee.GetType().GetMethod(cmd.FuncName);
// create parameter list
ParameterInfo[] paramInfoLst = method.GetParameters();
Object[] paramLst = new Object[paramInfoLst.Length];
for(int i = 0; i < paramInfoLst.Length; ++i) {
paramLst[i] = TypeDescriptor.GetConverter(paramInfoLst[i].ParameterType).ConvertFrom(argv[i + 1]);
}
// call methord with parameter list
method.Invoke(cmd.Callee, paramLst);
return true;
}
static private string[] ParseArguments(string commandLine) {
char[] parmChars = commandLine.ToCharArray();
bool inQuote = false;
for (int index = 0; index < parmChars.Length; index++)
{
if (parmChars[index] == '"')
inQuote = !inQuote;
if (!inQuote && Char.IsWhiteSpace(parmChars[index]))
parmChars[index] = '\n';
}
// remove double quote from begin and end
string[] result = new string(parmChars).Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
for(int i = 0; i< result.Length; i++) {
result[i] = result[i].Trim('"');
}
return result;
}
}
TestDebugConsole.cs
using System;
using System.ComponentModel;
using UnityEngine;
[TypeConverter(typeof(JPointConverter))]
public class JPoint {
public int X;
public int Y;
public JPoint(int x, int y) {
X = x;
Y = y;
}
}
public class JPointConverter : TypeConverter {
// must implement functions CanConvertFrom¡¢CanConvertTo¡¢ConvertFrom and ConvertTo.
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType is string) {
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string) {
string tmp =(string) value;
string[] point = tmp.Split('#');
int x = (int)Convert.ToInt32(point[0]);
int y = (int)Convert.ToInt32(point[1]);
return new JPoint(x, y);
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
return base.ConvertTo(context, culture, value, destinationType);
}
}
public class DebugConsoleTest : MonoBehaviour {
void Start() {
DebugConsole.RegisterCommand("output", this, "OutputMessage");
DebugConsole.RegisterCommand("point", this, "CreatePoint");
}
public void OutputMessage(string str) {
Debug.Log(str);
}
public void CreatePoint(JPoint point) {
Debug.Log("JPoint x: " + point.X + " y: " + point.Y);
}
void OnGUI() {
if (GUILayout.Button("Test")) {
DebugConsole.Execute("output hello!");
DebugConsole.Execute("point 1#3");
}
}
}
|
|