015-熱更新之xlua語言二
因為我們在前面已經花了大量的時間來學習lua,所以我們在本節就會結束xlua的部分。
2.3更輕量的by value方式:映射到dictionary<>,list<>。不想定義class或者interface的話,我們可以考慮用這個,前提table下key和value的類型都是一致的。
Dictionary<string, object> dict = luaenv.Global.Get<Dictionary<string, object>>("person"); foreach (string key in dict.Keys) { print(key+ "-" + dict[key]); }
這個就是通過dictionary的方式來完成的,不過它有一個註意點是它只能輸出有鍵值對的table,其他的形式它是映射不出來的。那麽我們應該如果去解決這個問題呢?這裏就要用到的是list<>了,但是這個集合也有一個要註意的是它只能映射數組類型的table,所以我們需要將兩者相結合來使用,下面是list的代碼:
List<object> listTxt = luaenv.Global.Get<List<object>>("person"); foreach (objecto in listTxt) { print(o); }
2.4另外一種方式 by ref方式:映射到luatable類 這種方式的好處也不需要生成代碼,但也有一點問題,比較慢。我們不建議使用這種方式,建議使用第二種方式。其實這種方式是插件幫我們寫好的,我們只需要直接調用就行了,代碼如下:
LuaTable tab = luaenv.Global.Get<LuaTable>("person"); print(tab.Get<string>("name"));
這四種方式我們已經全部介紹了一遍,我們發現其實他們用的都是同一個方法luaenv.Golbal.Get<T>("name")的形式,這也就說明了xlua的方便性,我們只需要簡單的創建xlua虛擬機就行了,這樣大大的節約了時間,加快代碼的效率。
三、訪問一個全局的function
我們現在發現xlua只用一個Get,但是不同的是類型映射。
1.映射到delegate
這種方式是建議的方式,性能好很多,而且類型安全。缺點是要生成代碼。在這裏首先要回顧一下delegate,因為在現在這個階段我用的比較少,所以有點忘記了,有必要再去看看。
c#中的委托(delegate)類似c或c++中函數的指針。委托(delegate)是存有對某個方法的引用的一種引用類型變量。引用可在運行時被改變。委托(delegate)特別用於實現事件和回調函數。所有的委托(delegate)都派生自system.delegate類。上面說delegate可以理解成指針。我們把delegate實例化出來後,就可以給裏面傳遞一個方法,這樣就是間接的引用了,所以我們寫下如下的代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 委托 { delegate int NumberChanger(int n); class Program { static int num = 10; public static int AddNum(int p) { num += p; return num; } public static int MultNum(int q) { num *= q; return q; } public static int GetNum() { return num; } static void Main(string[] args) { //創建委托實例 NumberChanger nc1 = new NumberChanger(AddNum); NumberChanger nc2 = new NumberChanger(MultNum); //使用委托對象調用方法 nc1(25); Console.WriteLine("Value of Num:{0}", GetNum()); nc2(25); Console.WriteLine("value of Num:{0}", GetNum()); Console.ReadKey(); } } }
nc1(24)雖然是給委托賦值的,但是nc1是引用AddNum()這個方法的,委托會調用這個方法,這實際上就是一種引用。經過我們這樣的梳理,我們就不會對委托產生迷茫了。好了我們繼續剛才的話題。
在這裏我們有一個問題,如果lua中的函數有返回值怎麽辦呢?lua中是可以返回多個返回值的,而c#只能返回一個返回值,我們看下面的代碼:
Add add = luaenv.Global.Get<Add>("method"); int resa;int resb; int res=add(34, 67,out resa,out resb); print(res+" "+resa + " " + resb); add = null; luaenv.Dispose(); } [CSharpCallLua] delegate int Add(int a, int b,out int resa,out int resb);
使用out就行了,我們就能解決返回值不一致的問題。效果如下:
2.映射到LuaFunction這種凡是的優缺點剛好和第一種相反。使用也簡單,LuaFunction上有個變參的call函數,可以傳遞任意類型,任意個數的參數,返回值是object的數組,對應於lua的多返回值。
LuaFunction func = luaenv.Global.Get<LuaFunction>("method"); object[] os = func.Call(1, 2); foreach (object o in os) { print(o); }
Lua調用從C#
本部分也是比較簡單的。我們只說兩個部分。廢話不多說,我們就向下看吧。
1.new C#對象
我們創建一個txt文件LuaCallCSharp.lua.txt 在裏面寫CS.UnityEngine.GameObject() 在C#中我們寫
LuaEnv luaenv = new LuaEnv();
luaenv.DoString("require ‘LuaCallCSharp‘");
luaenv.Dispose();
這樣就會在unity中創建一個gameobject了。
2.Lua訪問c#中成員屬性和方法
local gameObject=CS.UnityEngine.GameObject local camera=gameObject.Find("Main Camera") camera.name="666" local Cam01=camera:GetComponent("Camera") gameObject.Destroy(Cam01)
這樣寫的效果就是將unity中的Main Camera的名字改成666,並將Main Camera身上的Camera給禁用掉。這樣就能完成lua對c#的訪問。好了,所有的xlua內容今天全部完成了,我們在下一節的時候,將會用xlua開發一個案例,一起學習吧。
015-熱更新之xlua語言二