static void Run() { string serverroot = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets")); KillRunningServer(); string model = "SimpleHTTPServer"; ProcessStartInfo startInfo = new ProcessStartInfo("python", string.Format("-m {0} {1}", model, port)); startInfo.WorkingDirectory = serverroot; startInfo.UseShellExecute = false; startInfo.CreateNoWindow = true; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; Process launchProcess = Process.Start(startInfo); if (launchProcess == null || launchProcess.HasExited == true || launchProcess.Id == 0) { Debugger.LogError("Unable Start AssetServer process"); } else { instance.m_serverPID = launchProcess.Id; Debugger.Log("Local AssetServer Listen: {0}, Root Dir: {1}", port, serverroot); } }
public Sprite loadSkillIcon(string iconName) { if (iconName.isNullOrEmpty()) { Debugger.LogError("load skill icon name is null"); return(null); } Sprite sprite = UIResourceLoader.inst.getSkillIcon(iconName); return(sprite); }
public static int loader(IntPtr L) { // Get script to load string fileName = string.Empty; fileName = LuaDLL.lua_tostring(L, 1); //fileName = fileName.Replace('.', '/'); //fileName += ".lua"; // string lowerName = fileName.ToLower(); // if (lowerName.EndsWith(".lua")) { // int index = fileName.LastIndexOf('.'); // fileName = fileName.Substring(0, index); // } fileName = fileName.Replace('.', '/'); //+ ".lua"; /* * // Load with Unity3D resources * byte[] text = Load(fileName); * * if( text == null ) * { * return 0; * } * LuaDLL.luaL_loadbuffer(L, text, text.Length, fileName); */ LuaScriptMgr mgr = LuaScriptMgr.GetMgrFromLuaState(L); if (mgr == null) { return(0); } LuaDLL.lua_pushstdcallcfunction(L, mgr.lua.tracebackFunction); int oldTop = LuaDLL.lua_gettop(L); byte[] text = LuaStatic.Load(fileName); if (text == null) { if (!fileName.Contains("mobdebug")) { Debugger.LogError("Loader lua file failed: {0}", fileName); } LuaDLL.lua_pop(L, 1); return(0); } if (LuaDLL.luaL_loadbuffer(L, text, text.Length, fileName) != 0) { mgr.lua.ThrowExceptionFromError(oldTop); LuaDLL.lua_pop(L, 1); } return(1); }
public virtual int BeginPCall(TracePCall trace = TracePCall.Trace) { #if UNITY_EDITOR if (oldTop != -1) { //整个调用过程未完成被嵌套调用回自己 Debugger.LogError("you muse call EndPCall before call BeginPCall again"); } #endif this.trace = trace; oldTop = luaState.BeginPCall(reference, trace); return(oldTop); }
public void PCall() { #if UNITY_EDITOR if (oldTop == -1) { Debugger.LogError("you muse call BeginPCall before PCall"); } #endif stackPos = oldTop + 1; string error = luaState.PCall(argCount, trace != TracePCall.Ignore ? oldTop : 0); ThrowException(error); }
public object this[string fullPath] { get { int newTop = LuaDLL.lua_gettop(this.L); string[] array = fullPath.Split(new char[] { '.' }); LuaDLL.lua_getglobal(this.L, array[0]); object @object = this.translator.getObject(this.L, -1); if (array.Length > 1) { string[] array2 = new string[array.Length - 1]; Array.Copy(array, 1, array2, 0, array.Length - 1); @object = this.getObject(array2); } LuaDLL.lua_settop(this.L, newTop); return(@object); } set { int newTop = LuaDLL.lua_gettop(this.L); string[] array = fullPath.Split(new char[] { '.' }); if (array.Length == 1) { this.translator.push(this.L, value); LuaDLL.lua_setglobal(this.L, fullPath); } else { LuaDLL.lua_rawglobal(this.L, array[0]); if (LuaDLL.lua_type(this.L, -1) == LuaTypes.LUA_TNIL) { Debugger.LogError("Table {0} not exists", new object[] { array[0] }); LuaDLL.lua_settop(this.L, newTop); return; } string[] array2 = new string[array.Length - 1]; Array.Copy(array, 1, array2, 0, array.Length - 1); this.setObject(array2, value); } LuaDLL.lua_settop(this.L, newTop); } }
/* * Excutes a Lua file and returns all the chunk's return * values in an array */ public object[] DoFile(string fileName, LuaTable env) { LuaDLL.lua_pushstdcallcfunction(L, tracebackFunction); int oldTop = LuaDLL.lua_gettop(L); // Load with Unity3D resources byte[] text = LuaStatic.Load(fileName); // Debugger.LogWarning("---------------" + fileName); if (text == null) { if (!fileName.Contains("mobdebug")) { Debugger.LogError("Loader lua file failed: {0}", fileName); } LuaDLL.lua_pop(L, 1); return(null); } // string luafile = Util.LuaPath(fileName); //Encoding.UTF8.GetByteCount(text) int len = LuaStatic.getBytesLength(text); if (LuaDLL.luaL_loadbuffer(L, text, len, fileName) == 0) { if (env != null) { env.push(L); //LuaDLL.lua_setfenv(L, -1); LuaDLL.lua_setfenv(L, -2); } if (LuaDLL.lua_pcall(L, 0, -1, -2) == 0) { object[] results = translator.popValues(L, oldTop); LuaDLL.lua_pop(L, 1); return(results); } else { ThrowExceptionFromError(oldTop); LuaDLL.lua_pop(L, 1); } } else { ThrowExceptionFromError(oldTop); LuaDLL.lua_pop(L, 1); } return(null); // Never reached - keeps compiler happy }
/* * Pushes a new object into the Lua stack with the provided * metatable */ private void pushNewObject(IntPtr luaState, object o, int index, string metatable) { //LuaDLL.luaL_getmetatable(luaState, "luaNet_objects"); LuaDLL.lua_getref(luaState, weakTableRef); LuaDLL.luanet_newudata(luaState, index); if (metatable == "luaNet_metatable") { // Gets or creates the metatable for the object's type //string meta = t.AssemblyQualifiedName //LuaDLL.luaL_getmetatable(luaState, meta); Type t = o.GetType(); PushMetaTable(luaState, o.GetType()); if (LuaDLL.lua_isnil(luaState, -1)) { string meta = t.AssemblyQualifiedName; Debugger.LogError("Create not wrap ulua type:" + meta); LuaDLL.lua_settop(luaState, -2); LuaDLL.luaL_newmetatable(luaState, meta); LuaDLL.lua_pushstring(luaState, "cache"); LuaDLL.lua_newtable(luaState); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushlightuserdata(luaState, LuaDLL.luanet_gettag()); LuaDLL.lua_pushnumber(luaState, 1); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__index"); LuaDLL.lua_pushstring(luaState, "luaNet_indexfunction"); LuaDLL.lua_rawget(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__gc"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__tostring"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__newindex"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.newindexFunction); LuaDLL.lua_rawset(luaState, -3); } } else { LuaDLL.luaL_getmetatable(luaState, metatable); } LuaDLL.lua_setmetatable(luaState, -2); LuaDLL.lua_pushvalue(luaState, -1); LuaDLL.lua_rawseti(luaState, -3, index); LuaDLL.lua_remove(luaState, -2); }
public bool GetDataExistRef <T>(T o, out int index) { index = -1; #if UNITY_EDITOR Type dataType = TypeTraits <T> .type; Type dataOriginType = o.GetType(); if (!TypeChecker.IsValueType(dataOriginType) && dataType != objType) { Debugger.LogError("strict object type required, got :" + dataOriginType); return(false); } #endif return(StackDataMapping <T> .InstanceGet(this).TryGetValue(o, out index)); }
public bool PCall(int oldTop, int args) { if (LuaDLL.lua_pcall(L, args, -1, -args - 2) != 0) { string err = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_settop(L, oldTop - 1); if (err == null) { err = "Unknown Lua Error"; } Debugger.LogError(err); return(false); } return(true); }
/// <summary> /// 我添加的两个相应的函数 /// </summary> /// <param name="fileName"></param> /// <param name="chunk"></param> /// <returns></returns> public object[] DoStringFile(string fileName, string chunk) { LuaDLL.lua_pushstdcallcfunction(L, tracebackFunction); int oldTop = LuaDLL.lua_gettop(L); LuaTable env = null; // Load with Unity3D resources byte[] text = Encoding.UTF8.GetBytes(chunk); if (text == null) { Debugger.LogError("Loader lua file failed: {0}", fileName); LuaDLL.lua_pop(L, 1); return(null); } //Encoding.UTF8.GetByteCount(text) if (LuaDLL.luaL_loadbuffer(L, text, text.Length, fileName) == 0) { if (env != null) { env.push(L); //LuaDLL.lua_setfenv(L, -1); LuaDLL.lua_setfenv(L, -2); } if (LuaDLL.lua_pcall(L, 0, -1, -2) == 0) { object[] results = translator.popValues(L, oldTop); LuaDLL.lua_pop(L, 1); return(results); } else { ThrowExceptionFromError(oldTop); LuaDLL.lua_pop(L, 1); } } else { ThrowExceptionFromError(oldTop); LuaDLL.lua_pop(L, 1); } return(null); // Never reached - keeps compiler happy }
private static void PushPreLoadType(IntPtr L, object o, Type type) { LuaCSFunction preModule = LuaStatic.GetPreModule(L, type); if (preModule != null) { ToLua.LuaPCall(L, preModule); int metaReference = LuaStatic.GetMetaReference(L, type); if (metaReference > 0) { ToLua.PushUserData(L, o, metaReference); return; } } LuaDLL.lua_pushnil(L); Debugger.LogError("Type {0} not wrap to lua", LuaMisc.GetTypeName(type)); }
public static int loader(IntPtr L) { // Get script to load string fileName = String.Empty; fileName = LuaDLL.lua_tostring(L, 1); fileName = fileName.Replace('.', '/'); fileName += ".lua"; /* * // Load with Unity3D resources * byte[] text = Load(fileName); * * if( text == null ) * { * return 0; * } * * LuaDLL.luaL_loadbuffer(L, text, text.Length, fileName); */ LuaScriptMgr mgr = LuaScriptMgr.GetMgrFromLuaState(L); if (mgr == null) { return(0); } LuaDLL.lua_pushstdcallcfunction(L, mgr.lua.tracebackFunction); int oldTop = LuaDLL.lua_gettop(L); byte[] text = LuaStatic.Load(fileName); if (text == null) { Debugger.LogError("Loader lua file failed: {0}", fileName); LuaDLL.lua_pop(L, 1); return(0); } if (LuaDLL.luaL_loadbuffer(L, text, text.Length, fileName) != 0) { mgr.lua.ThrowExceptionFromError(oldTop); LuaDLL.lua_pop(L, 1); } return(1); }
public object this[string fullPath] { get { object returnValue = null; int oldTop = LuaAPI.lua_gettop(L); string[] path = fullPath.Split(new char[] { '.' }); LuaAPI.lua_getglobal(L, path[0]); returnValue = translator.getObject(L, -1); if (path.Length > 1) { string[] remainingPath = new string[path.Length - 1]; Array.Copy(path, 1, remainingPath, 0, path.Length - 1); returnValue = getObject(remainingPath); } LuaAPI.lua_settop(L, oldTop); return(returnValue); } set { int oldTop = LuaAPI.lua_gettop(L); string[] path = fullPath.Split(new char[] { '.' }); if (path.Length == 1) { translator.push(L, value); LuaAPI.lua_setglobal(L, fullPath); } else { LuaAPI.lua_getglobal(L, path[0]); LuaTypes type = LuaAPI.lua_type(L, -1); if (type == LuaTypes.LUA_TNIL) { Debugger.LogError("Table {0} not exists", path[0]); LuaAPI.lua_settop(L, oldTop); return; } string[] remainingPath = new string[path.Length - 1]; Array.Copy(path, 1, remainingPath, 0, path.Length - 1); setObject(remainingPath, value); } LuaAPI.lua_settop(L, oldTop); } }
/* * Calls the function casting return values to the types * in returnTypes */ internal object[] call(object[] args, Type[] returnTypes) { int nArgs = 0; LuaScriptMgr.PushTraceBack(L); int oldTop = LuaDLL.lua_gettop(L); if (!LuaDLL.lua_checkstack(L, args.Length + 6)) { LuaDLL.lua_pop(L, 1); throw new LuaException("Lua stack overflow"); } push(L); if (args != null) { nArgs = args.Length; for (int i = 0; i < args.Length; i++) { PushArgs(L, args[i]); } } int error = LuaDLL.lua_pcall(L, nArgs, -1, -nArgs - 2); if (error != 0) { string err = LuaDLL.lua_tostring(L, -1); LuaDLL.lua_settop(L, oldTop - 1); if (err == null) { err = "Unknown Lua Error"; } Debugger.LogError(err); LuaDLL.lua_settop(L, oldTop - 1); return(null); } object[] ret = returnTypes != null?translator.popValues(L, oldTop, returnTypes) : translator.popValues(L, oldTop); LuaDLL.lua_settop(L, oldTop - 1); return(ret); }
public object[] DoFile(string fileName, LuaTable env) { LuaDLL.lua_pushstdcallcfunction(this.L, this.tracebackFunction, 0); int oldTop = LuaDLL.lua_gettop(this.L); byte[] array = LuaStatic.Load(fileName); if (array == null) { if (!fileName.Contains("mobdebug")) { Debugger.LogError("Loader lua file failed: {0}", new object[] { fileName }); } LuaDLL.lua_pop(this.L, 1); return(null); } string name = Util.LuaPath(fileName); if (LuaDLL.luaL_loadbuffer(this.L, array, array.Length, name) == 0) { if (env != null) { env.push(this.L); LuaDLL.lua_setfenv(this.L, -2); } if (LuaDLL.lua_pcall(this.L, 0, -1, -2) == 0) { object[] result = this.translator.popValues(this.L, oldTop); LuaDLL.lua_pop(this.L, 1); return(result); } this.ThrowExceptionFromError(oldTop); LuaDLL.lua_pop(this.L, 1); } else { this.ThrowExceptionFromError(oldTop); LuaDLL.lua_pop(this.L, 1); } return(null); }
public static void PushValue(IntPtr L, ValueType v) { if (v == null) { LuaDLL.lua_pushnil(L); return; } Type type = v.GetType(); int reference = LuaStatic.GetMetaReference(L, type); ObjectTranslator translator = ObjectTranslator.Get(L); if (reference > 0) { int index = translator.AddObject(v); LuaDLL.tolua_pushnewudata(L, reference, index); } else { LuaCSFunction LuaOpenLib = LuaStatic.GetPreModule(L, type); if (LuaOpenLib != null) { #if UNITY_EDITOR Debugger.LogWarning("register PreLoad type {0} to lua", LuaMisc.GetTypeName(type)); #endif LuaOpenLib(L); reference = LuaStatic.GetMetaReference(L, type); if (reference > 0) { int index = translator.AddObject(v); LuaDLL.tolua_pushnewudata(L, reference, index); return; } } //类型未Wrap LuaDLL.lua_pushnil(L); Debugger.LogError("Type {0} not wrap to lua", LuaMisc.GetTypeName(type)); } }
public static int loader(IntPtr L) { string text = string.Empty; text = LuaDLL.lua_tostring(L, 1); string text2 = text.ToLower(); if (text2.EndsWith(".lua")) { int length = text.LastIndexOf('.'); text = text.Substring(0, length); } text = text.Replace('.', '/') + ".lua"; LuaScriptMgr mgrFromLuaState = LuaScriptMgr.GetMgrFromLuaState(L); if (mgrFromLuaState == null) { return(0); } LuaDLL.lua_pushstdcallcfunction(L, mgrFromLuaState.lua.tracebackFunction, 0); int oldTop = LuaDLL.lua_gettop(L); byte[] array = LuaStatic.Load(text); if (array == null) { if (!text.Contains("mobdebug")) { Debugger.LogError("Loader lua file failed: {0}", new object[] { text }); } LuaDLL.lua_pop(L, 1); return(0); } if (LuaDLL.luaL_loadbuffer(L, array, array.Length, text) != 0) { mgrFromLuaState.lua.ThrowExceptionFromError(oldTop); LuaDLL.lua_pop(L, 1); } return(1); }
public bool Add <T>(T obj, out int pos) { NodeBase node = null; pos = -1; var head = PoolNode <T> .head; if (head.index != 0) { pos = head.index; node = list[pos]; var gNode = node as PoolNode <T>; gNode.obj = obj; gNode.eleType = obj.GetType(); head.index = node.index; } else { if (count == list.Length) { EnsureCapacity(count + 1); } pos = count; node = new PoolNode <T>(pos, obj); list[pos] = node; count++; } #if UNITY_EDITOR Type dataType = TypeTraits <T> .type; if (node.bObjectType && dataType != objType) { Debugger.LogError("strict object type required, got :" + node.eleType); return(false); } #endif StackDataMapping <T> .InstanceGet(this).Add(obj, pos); return(true); }
public void PCall() { #if UNITY_EDITOR if (oldTop == -1) { Debugger.LogError("You must call BeginPCall before calling PCall"); } #endif stackPos = oldTop + 1; try { luaState.PCall(argCount, oldTop); } catch (Exception e) { EndPCall(); throw e; } }
static string GetFileContentMD5(string file) { try { FileStream fs = new FileStream(file, FileMode.Open); System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(fs); fs.Close(); StringBuilder sb = StringBuilderCache.Acquire(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return(StringBuilderCache.GetStringAndRelease(sb)); } catch (System.Exception ex) { Debugger.LogError("Md5file() fail, error:" + ex.Message); return(string.Empty); } }
public void PushNewValueObject(IntPtr luaState, object o, int index) { LuaDLL.luanet_newudata(luaState, index); //string meta = GetAQName(o.GetType()); //LuaDLL.luaL_getmetatable(luaState, meta); Type t = o.GetType(); PushMetaTable(luaState, o.GetType()); if (LuaDLL.lua_isnil(luaState, -1)) { string meta = t.AssemblyQualifiedName; Debugger.LogError("Create not wrap ulua type:" + meta); LuaDLL.lua_settop(luaState, -2); LuaDLL.luaL_newmetatable(luaState, meta); LuaDLL.lua_pushstring(luaState, "cache"); LuaDLL.lua_newtable(luaState); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushlightuserdata(luaState, LuaDLL.luanet_gettag()); LuaDLL.lua_pushnumber(luaState, 1); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__index"); LuaDLL.lua_pushstring(luaState, "luaNet_indexfunction"); LuaDLL.lua_rawget(luaState, (int)LuaIndexes.LUA_REGISTRYINDEX); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__gc"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.gcFunction); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__tostring"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.toStringFunction); LuaDLL.lua_rawset(luaState, -3); LuaDLL.lua_pushstring(luaState, "__newindex"); LuaDLL.lua_pushstdcallcfunction(luaState, metaFunctions.newindexFunction); LuaDLL.lua_rawset(luaState, -3); } LuaDLL.lua_setmetatable(luaState, -2); }
static void PushPreLoadType(IntPtr L, object o, Type type) { LuaCSFunction LuaOpenLib = LuaStatic.GetPreModule(L, type); if (LuaOpenLib != null) { #if UNITY_EDITOR Debugger.LogWarning("register PreLoad type {0} to lua", LuaMisc.GetTypeName(type)); #endif LuaPCall(L, LuaOpenLib); int reference = LuaStatic.GetMetaReference(L, type); if (reference > 0) { PushUserData(L, o, reference); return; } } //类型未Wrap LuaDLL.lua_pushnil(L); Debugger.LogError("Type {0} not wrap to lua", LuaMisc.GetTypeName(type)); }
public static void LogError(object message) { Debugger.LogError(message.ToString()); }
static void AutoAddBaseType(BindType bt, bool beDropBaseType) { Type t = bt.baseType; if (t == null) { return; } if (CustomSettings.sealedList.Contains(t)) { CustomSettings.sealedList.Remove(t); Debugger.LogError("{0} not a sealed class, it is parent of {1}", LuaMisc.GetTypeName(t), bt.name); } if (t.IsInterface) { Debugger.LogWarning("{0} has a base type {1} is Interface, use SetBaseType to jump it", bt.name, t.FullName); bt.baseType = t.BaseType; } else if (dropType.IndexOf(t) >= 0) { Debugger.LogWarning("{0} has a base type {1} is a drop type", bt.name, t.FullName); bt.baseType = t.BaseType; } else if (!beDropBaseType || baseType.IndexOf(t) < 0) { int index = allTypes.FindIndex((iter) => { return(iter.type == t); }); if (index < 0) { #if JUMP_NODEFINED_ABSTRACT if (t.IsAbstract && !t.IsSealed) { Debugger.LogWarning("not defined bindtype for {0}, it is abstract class, jump it, child class is {1}", LuaMisc.GetTypeName(t), bt.name); bt.baseType = t.BaseType; } else { Debugger.LogWarning("not defined bindtype for {0}, autogen it, child class is {1}", LuaMisc.GetTypeName(t), bt.name); bt = new BindType(t); allTypes.Add(bt); } #else Debugger.LogWarning("not defined bindtype for {0}, autogen it, child class is {1}", LuaMisc.GetTypeName(t), bt.name); bt = new BindType(t); allTypes.Add(bt); #endif } else { return; } } else { return; } AutoAddBaseType(bt, beDropBaseType); }
/* * Indexer for global variables from the LuaInterpreter * Supports navigation of tables by using . operator */ public object this[string fullPath] { get { object returnValue = null; int oldTop = LuaDLL.lua_gettop(L); string[] path = fullPath.Split(new char[] { '.' }); LuaDLL.lua_getglobal(L, path[0]); returnValue = translator.getObject(L, -1); if (path.Length > 1) { string[] remainingPath = new string[path.Length - 1]; Array.Copy(path, 1, remainingPath, 0, path.Length - 1); returnValue = getObject(remainingPath); } LuaDLL.lua_settop(L, oldTop); return(returnValue); } set { int oldTop = LuaDLL.lua_gettop(L); string[] path = fullPath.Split(new char[] { '.' }); if (path.Length == 1) { translator.push(L, value); LuaDLL.lua_setglobal(L, fullPath); } else { //LuaDLL.lua_getglobal(L, path[0]); LuaDLL.lua_rawglobal(L, path[0]); LuaTypes type = LuaDLL.lua_type(L, -1); if (type == LuaTypes.LUA_TNIL) { Debugger.LogError("Table {0} not exists", path[0]); LuaDLL.lua_settop(L, oldTop); return; } string[] remainingPath = new string[path.Length - 1]; Array.Copy(path, 1, remainingPath, 0, path.Length - 1); setObject(remainingPath, value); } LuaDLL.lua_settop(L, oldTop); // Globals auto-complete // comment by topameng, too many time cost, you shound register you type in other position /*if (value == null) * { * // Remove now obsolete entries * globals.Remove(fullPath); * } * else * { * // Add new entries * if (!globals.Contains(fullPath)) * registerGlobal(fullPath, value.GetType(), 0); * }*/ } }
public static void LogError(string str, object arg0, object arg1, object arg2) { Debugger.LogError(string.Format(str, arg0, arg1, arg2)); }
public static void LogError(string str, params object[] param) { Debugger.LogError(string.Format(str, param)); }