ToLua熱更新之LuaFramework框架之編寫Lua邏輯(3)
1、Lua的Update方法
第一篇“程式碼熱更新”演示了用lua列印HelloWorld的方法,第二篇“資源熱更新”演示了載入坦克模型的方法。這一篇要把兩者結合起來,用lua實現“用鍵盤控制坦克移動”的功能。用Lua和用c#編寫的Unity3D程式大同小異,只需正確使用API即可,Lua語言的知識請參見《programing in lua》這本書。
1)Update方法
出於效率的考慮,tolua提供了名為UpdateBeat的物件,在LuaFramework中,只需給UpdateBeat添加回調函式,該函式便會每幀執行,相當於Monobehaviour的Update方法。Lua程式碼如下所示:
function Main()
UpdateBeat:Add(Update, self)
end
function Update()
LuaFramework.Util.Log("每幀執行一次");
end
除了UpdateBeat,tolua還提供了LateUpdateBeat和FixedUpdateBeat,對應於Monobehaviour中的LateUpdate和FixedUpdate。
2)控制坦克
現在編寫“用鍵盤控制坦克移動”的lua程式碼,載入坦克模型後,使用UpdateBeat註冊每幀執行的Update方法,然後在Update方法中呼叫UnityEngine.Input等API實現功能。程式碼如下:
local go; --載入的坦克模型 --主入口函式。從這裡開始lua邏輯 function Main() LuaHelper = LuaFramework.LuaHelper; resMgr = LuaHelper.GetResManager(); resMgr:LoadPrefab('tank', { 'TankPrefab' }, OnLoadFinish); end --載入完成後的回撥-- function OnLoadFinish(objs) go = UnityEngine.GameObject.Instantiate(objs[0]); LuaFramework.Util.Log("LoadFinish"); UpdateBeat:Add(Update, self) end --每幀執行 function Update() LuaFramework.Util.Log("每幀執行"); local Input = UnityEngine.Input; local horizontal = Input.GetAxis("Horizontal"); local verticla = Input.GetAxis("Vertical"); local x = go.transform.position.x + horizontal local z = go.transform.position.z + verticla go.transform.position = Vector3.New(x,0,z) end
運行遊戲,即可用鍵盤的控制坦克移動。
圖:用鍵盤的控制坦克移動
2、自定義API
框架中提供了數十個可供lua呼叫的c#類,但這些往往不夠用,需要自己新增,本節將介紹新增自定義API的方法。
1)編寫c#類
例如,編寫TestLuaFun.類,它包含一個靜態方法Log,會打印出“《Unity3D網路遊戲實戰》是一本好書!”和“《手把手教你用c#製作rpg遊戲》也是一本好書!”兩行文字。
using UnityEngine;
using System.Collections;
public class TestLuaFun
{
public static void Log()
{
Debug.Log("《Unity3D網路遊戲實戰》是一本好書!");
Debug.Log("《手把手教你用c#製作rpg遊戲》也是一本好書!");
}
}
2)修改CustomSetting
開啟CustomSetting.cs,在customTypeList中新增一句“_GT(typeof(TestLuaFun))”。
圖:修改CustomSetting
3)生成wrap檔案
點選選單欄的Lua→Clear wrap files和Lua→Generate All,重新生成wrap檔案。由於剛剛在customTypeList添加了類,所以會生成TestLuaFun類的wrap檔案TestLuaFunWrap.cs。
圖:生成wrap檔案
開啟TestLuaFunWrap.cs,可以看到TestLuaFun註冊了Log方法。關於static int Log(IntPtr L)的具體含義,請參見《programing in lua》中lua與c++互動的章節。
圖:TestLuaFunWrap
4)測試API
修改main.lua,呼叫TestLuaFun.Log() ,即可看到效果。
--主入口函式。從這裡開始lua邏輯
function Main()
TestLuaFun.Log()
end
圖:呼叫自定義API
3、原理
tolua實現了LuaInterface,拋開luaFramework,只需建立lua虛擬機器,便能在c#中呼叫lua程式碼,如下所示。
using UnityEngine;
using System.Collections;
using LuaInterface;
public class test : MonoBehaviour
{
void Start ()
{
//初始化
LuaState lua = new LuaState();
LuaBinder.Bind(lua);
//lua程式碼
string luaStr =
@"
print('hello tolua#, 廣告招租')
LuaFramework.Util.Log('HelloWorld');
TestLuaFun.Log()
";
//執行lua指令碼
lua.DoString(luaStr);
}
}
圖:建立lua虛擬機器,執行lua程式碼
實際上LuaFramework也是用了相似的方法,框架啟動後,會建立LuaManager、LuaLooper的例項。LuaManager建立lua虛擬機器並呼叫Main.lua的Main方法,LuaLooper處理了UpdateBeat相關的事情。如下所示:
圖:LuaManager的啟動過程