1. 程式人生 > >015-熱更新之xlua語言二

015-熱更新之xlua語言二

urn info 而且 .text 賦值 image global space 時間

因為我們在前面已經花了大量的時間來學習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 (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虛擬機就行了,這樣大大的節約了時間,加快代碼的效率。

三、訪問一個全局的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語言二