《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.準備
-
擷取tolua:https://github.com/topameng/tolua。
tolua是一個工具,将Unity的C#代碼包裝之後導出給LUA,同時提供了一些通路LUA的接口,使得Unity和LUA可以互相調用。
-
簡單起見,直接用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中實作的。