015-熱更新之xlua語言二

由於咱們在前面已經花了大量的時間來學習lua,因此咱們在本節就會結束xlua的部分。c++

2.3更輕量的by value方式:映射到dictionary<>,list<>。不想定義class或者interface的話,咱們能夠考慮用這個,前提table下key和value的類型都是一致的。c#

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 (object o 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虛擬機就好了,這樣大大的節約了時間,加快代碼的效率。函數

3、訪問一個全局的function性能

咱們如今發現xlua只用一個Get,可是不一樣的是類型映射。學習

1.映射到delegate ui

這種方式是建議的方式,性能好不少,並且類型安全。缺點是要生成代碼。在這裏首先要回顧一下delegate,由於在如今這個階段我用的比較少,因此有點忘記了,有必要再去看看。lua

c#中的委託(delegate)相似c或c++中函數的指針。委託(delegate)是存有對某個方法的引用的一種引用類型變量。引用可在運行時被改變。委託(delegate)特別用於實現事件和回調函數。全部的委託(delegate)都派生自system.delegate類。上面說delegate能夠理解成指針。咱們把delegate實例化出來後,就能夠給裏面傳遞一個方法,這樣就是間接的引用了,因此咱們寫下以下的代碼:spa

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開發一個案例,一塊兒學習吧。

相關文章
相關標籤/搜索