天天看點

ULUA的簡潔用法1.原理2.準備3.添加C#中間層4.添加LUA腳本層5.輔助腳本6.總結

《ULUA的簡潔用法》

作者: 遊藍海

文章連結:http://blog.csdn.net/you_lan_hai/article/details/51059510

轉載請注明出處

2017.4.23修改:看到不少朋友關注本篇文章,我又總結了另外一套更簡單的用法,見《ULUA的簡潔用法(二)》

ULUA(http://www.ulua.org/index.html)所推薦的幾種framework雖然功能強大,但是結構比較複雜,對于unity初學者來說太過麻煩和備援。是以我自己總結了一套很簡潔的用法,抛開MVC和各種架構,直接使用tolua(https://github.com/topameng/tolua)實作Unity和LUA的互動。

本文介紹的是以代碼,我已經上傳到了GitHub,連結見文章末尾。下面介紹實作的詳細步驟。

1.原理

給GameObject添加上一個C#腳本元件作為中間層,在中間層上綁定上一個LUA腳本,将Unity的所有回調接口通過中間層傳遞到LUA。同時,LUA腳本也可以通過中間層操作GameObject。

2.準備

  1. 擷取tolua:https://github.com/topameng/tolua。

    tolua是一個工具,将Unity的C#代碼包裝之後導出給LUA,同時提供了一些通路LUA的接口,使得Unity和LUA可以互相調用。

  2. 簡單起見,直接用Unity編輯器打開tolua工程。

    本文使用的tolua版本是1.0.4,Unity版本是5.2.2。

3.添加C#中間層

建立C#腳本,命名為LuaBehaviourScript.cs。下面是檔案的核心内容(無關緊要的代碼已經删除,可在文章末尾連結中獲得完整代碼):

public class LuaBehaviourScript : MonoBehaviour {
    //記錄LUA子產品名稱
    public string           ScriptName;
    //記錄LUA腳本對象
    protected LuaTable      self_;

    protected void Awake()
    {
        //require lua檔案,得到傳回的LUA類
        LuaTable metatable = (LuaTable)LuaMainInstance.Instance.require(ScriptName);

        //從類中找到New函數
        LuaFunction lnew = (LuaFunction)metatable["New"];

        //執行New函數生成腳本對象
        object[] results = lnew.Call(metatable, this);

        //存貯腳本對象
        self_ = (LuaTable)results[];

        //給腳本對象設定上常用的屬性
        self_["transform"] = transform;
        self_["gameObject"] = gameObject;

        //嘗試調用腳本對象的Awake函數
        CallMethod("Awake");
    }
    protected object[] CallMethod(string func, params object[] args)
    {
        //查找LUA函數
        LuaFunction lfunc = (LuaFunction)self_[func];
        if(lfunc == null)
        {
            return null;
        }

        //調用LUA函數。等價于lua語句“self:func(...)”
        int oldTop = lfunc.BeginPCall();
        lfunc.Push(self_); //将self作為第一個參數傳入
        lfunc.PushArgs(args);
        lfunc.PCall();
        object[] objs = luaState_.CheckObjects(oldTop);
        lfunc.EndPCall();
        return objs;
    }
}
           

4.添加LUA腳本層

在Assets/Lua目錄下建立LUA腳本Test.lua,核心代碼如下:

--構造Test類
local Test = {}
Test.__index = Test --讓執行個體對象的__get方法指向Test類

--給Test類執行個體化一個對象
function Test.New(cls)
    local self = {}
    setmetatable(self, cls)
    return self
end

--Awake方法
function Test:Awake()
    print("Test:Awake", self)
end

--将類Test傳回。通過require函數的傳回值就可以擷取到此值了。
return Test
           

5.輔助腳本

由于各個GameObject的初始化先後順序不好統一,而且考慮到多個場景切換的情況,tolua提供的

LuaClient

就沒那麼好使了。是以我增加了一個

LuaMainInstance

的單例類,在其構造的時候就初始化一個全局的LuaState,供LUA腳本使用。

由于不使用

LuaClient

,是以

LuaLooper

也無法直接使用了,我就添加了一個派生類

LuaWatchdog

,用于啟動

LuaLooper

6.總結

将LuaBehaviourScript.cs添加給GameObject之後,并設定上要綁定的Lua子產品名稱。當GameObject Awake的時候,會自動加載綁定的LUA腳本檔案,并建立出腳本對象。後續所有的Untity回調函數,都會通過腳本對象傳遞到LUA層。

完整代碼下載下傳位址:https://github.com/youlanhai/tolua

打開Test場景,點選播放,你會看到立方體在垂直方向上下移動。移動的邏輯,就是在Test.lua中實作的。