Unity WebGL MoonSharp崩溃问题
当前Unity的代码更新方案基本都选择的ULua,而我们项目还需要考虑Web平台,ULua不支持WebGL,所以决定选择MoonSharp。MoonSharp(http://www.moonsharp.org/)是一个纯C#实现的Lua解释器,支持多种平台。
测试环境:Unity5.4 + WebGL + MoonSharp 1.6.0.0
测试代码:
1 double MoonSharpFactorial() 2 { 3 string script = @" 4 -- defines a factorial function 5 function fact (n) 6 if (n == 0) then 7 return 1 8 else 9 return n*fact(n - 1) 10 end 11 end 12 13 return fact(5)"; 14 15 DynValue res = Script.RunString(script); 16 return res.Number; 17 }
在Web浏览器中却崩溃了,后经过定位发现是MoonSharp.Interpreter.Loaders.UnityAssetsScriptLoader.LoadResourcesWithReflection出错,Bug和我的修改已经在GitHub提交给作者了,预计很快会合并到主干代码中。
1 void LoadResourcesWithReflection(string assetsPath) 2 { 3 try 4 { 5 Type resourcesType = Type.GetType("UnityEngine.Resources, UnityEngine"); 6 Type textAssetType = Type.GetType("UnityEngine.TextAsset, UnityEngine"); 7 8 MethodInfo textAssetNameGet = textAssetType.GetProperty("name").GetGetMethod(); 9 MethodInfo textAssetTextGet = textAssetType.GetProperty("text").GetGetMethod(); 10 11 MethodInfo loadAll = resourcesType.GetMethod("LoadAll", 12 new Type[] { typeof(string), typeof(Type) }); 13 14 Array array = (Array)loadAll.Invoke(null, new object[] { assetsPath, textAssetType });//此处崩溃,估计是Unity导出代码有Bug 15 16 for (int i = 0; i < array.Length; i++) 17 { 18 object o = array.GetValue(i); 19 20 string name = textAssetNameGet.Invoke(o, null) as string; 21 string text = textAssetTextGet.Invoke(o, null) as string; 22 23 m_Resources.Add(name, text); 24 } 25 } 26 catch (Exception ex) 27 { 28 #if !PCL 29 Console.WriteLine("Error initializing UnityScriptLoader : {0}", ex); 30 #endif 31 } 32 }
可以改为
1 void LoadResourcesWithReflection(string assetsPath) 2 { 3 try 4 { 5 #if UNITY_WEBGL 6 UnityEngine.TextAsset[] arrayTextAsset = UnityEngine.Resources.LoadAll<UnityEngine.TextAsset>(assetsPath); 7 for (int i = 0; i < arrayTextAsset.Length; i++) 8 { 9 UnityEngine.TextAsset text = arrayTextAsset[i]; 10 m_Resources.Add(text.name, text.text); 11 } 12 return; 13 #endif 14 15 Type resourcesType = Type.GetType("UnityEngine.Resources, UnityEngine"); 16 Type textAssetType = Type.GetType("UnityEngine.TextAsset, UnityEngine"); 17 18 MethodInfo textAssetNameGet = textAssetType.GetProperty("name").GetGetMethod(); 19 MethodInfo textAssetTextGet = textAssetType.GetProperty("text").GetGetMethod(); 20 21 MethodInfo loadAll = resourcesType.GetMethod("LoadAll", 22 new Type[] { typeof(string), typeof(Type) }); 23 24 Array array = (Array)loadAll.Invoke(null, new object[] { assetsPath, textAssetType }); 25 26 for (int i = 0; i < array.Length; i++) 27 { 28 object o = array.GetValue(i); 29 30 string name = textAssetNameGet.Invoke(o, null) as string; 31 string text = textAssetTextGet.Invoke(o, null) as string; 32 33 m_Resources.Add(name, text); 34 } 35 } 36 catch (Exception ex) 37 { 38 #if !PCL 39 Console.WriteLine("Error initializing UnityScriptLoader : {0}", ex); 40 #endif 41 } 42 }