toLua與Xlua使用方法總結
阿新 • • 發佈:2020-12-08
兩者都是常見的基於Unity的熱更需求開發出來成熟方案。 實現原理是在Unity啟動後加載一個lua虛擬機器。解釋lua指令碼。再通過各種方法支援C# <> lua 層的互相呼叫。委託。反射。傳值傳址呼叫。
本處只作為初學者對比一下雙方在上手和使用時候的一些異同。以兩種方法實現的跳一跳小遊戲為例。
一 lua配置和exaple示例
1. tolua
2 xlua
二 lua Wrap檔案生成方法
1 tolua 根據配置檔案CustomSetting 指定相關的輸出目錄 需要註冊委託的類。事件。型別等
2 xlua 3種方式進行配置。
1) 使用標籤[CSharpCallLua] / [LuaCallCSharp] 自動識別 對應的類和方法 。
2) 靜態配置檔案 統一配置
3) 動態配置
三 lua啟動環境和C#呼叫lua
1 tolua 全域性統一的LuaClient。
直接載入lua檔案.使用*.lua檔案
public class LuaManager : MonoBehaviour { private static LuaManager _instance; public static LuaManager Instance{ get{ return _instance; } } private LuaClient _luaClient;public LuaClient LuaClient { get { return _luaClient; } } // Use this for initialization void Awake () { _instance = this; DontDestroyOnLoad(this.gameObject); _luaClient = this.gameObject.AddComponent<LuaClient>(); } }
//使用DoFile呼叫lua,使用CallFunc呼叫lua函式
LuaManager.Instance.LuaClient.luaState.DoFile("Login.lua"); LuaManager.Instance.LuaClient.CallFunc("Login.Awake", this.gameObject);
2 xlua 也是初始化1個luaenv後。為每個behavior建立一個獨立環境,防止lua全域性變數汙染。
將lua物件和函式以action方式來呼叫
xlua是通過ReadAllText 或者TextAsset 讀取txt的檔案流。使用 *.lua.txt檔案
internal static LuaEnv luaEnv = new LuaEnv();//all ua behaviour shared one luaenv only! void Awake() { scriptEnv = luaEnv.NewTable(); // 為每個指令碼設定一個獨立的環境,可一定程度上防止指令碼間全域性變數、函式衝突 LuaTable meta = luaEnv.NewTable(); meta.Set("__index", luaEnv.Global); scriptEnv.SetMetaTable(meta); meta.Dispose(); //繫結gameobject物件 scriptEnv.Set("self", this); //使用injection name/object 注入其他Unity物件 交給lua直接引用 foreach (var injection in injections) { scriptEnv.Set(injection.name, injection.value); } //scriptEnv 賦值 LuaTestScript 指令碼 luaEnv.DoString("require('Main')");//luarequire luaEnv.DoString("require('Continue')");//luarequire luaEnv.DoString(luaScript.text, "player", scriptEnv); //lua方法 繫結到Action luaAwake = scriptEnv.Get<Action<GameObject>>("awake"); scriptEnv.Get("start", out luaStart); scriptEnv.Get("update", out luaUpdate); scriptEnv.Get("ondestroy", out luaOnDestroy); scriptEnv.Get("onCollisionStay", out onCollisionStay); //UnityEngine.SceneManagement.SceneManager.LoadScene("Login"); if (luaAwake != null) { luaAwake(gameObject); } }
四 lua呼叫C#和Unity元件
1 tolua 在啟動main函式中初始化全域性引數
--主入口函式。從這裡開始lua邏輯 --這裡定義我們所需的全域性方法 function Main() GameObject = UnityEngine.GameObject Transform = UnityEngine.Transform ParticleSystem = UnityEngine.ParticleSystem Color = UnityEngine.Color Util = Util.New() SceneManagement = UnityEngine.SceneManagement Input = UnityEngine.Input KeyCode = UnityEngine.KeyCode Time = UnityEngine.Time Camera = UnityEngine.Camera AudioSource = UnityEngine.AudioSource Resources = UnityEngine.Resources www = UnityEngine.WWW boxCount=0 print("logic start") end --場景切換通知 function OnLevelWasLoaded(level) collectgarbage("collect") Time.timeSinceLevelLoad = 0 end function OnApplicationQuit() end
每個lua檔案通過一個table包裝成一個類
Continue = {} local this = Continue function this.ReStart(obj) local reStartBtn = obj.transform : Find("ReStart").gameObject UIEvent.AddButtonOnClick(reStartBtn, ReStartOnClick) end function ReStartOnClick () SceneManagement.SceneManager.LoadScene("Jump") end
2 xlua 使用CS.名稱空間.類名.方法 引用被標籤[LuaCallCSharp]的類和方法
--主入口函式。從這裡開始lua邏輯 --這裡定義我們所需的全域性方法 GameObject = CS.UnityEngine.GameObject Transform = CS.UnityEngine.Transform ParticleSystem = CS.UnityEngine.ParticleSystem Color = CS.UnityEngine.Color SceneManagement = CS.UnityEngine.SceneManagement Input = CS.UnityEngine.Input KeyCode = CS.UnityEngine.KeyCode Time = CS.UnityEngine.Time Camera = CS.UnityEngine.Camera AudioSource = CS.UnityEngine.AudioSource Resources = CS.UnityEngine.Resources www = CS.UnityEngine.WWW Vector3 = CS.UnityEngine.Vector3 Util = CS.XLuaTest.Util boxCount=0
local Util local LuaBoxControl --local ParticleSystem = UnityEngine.ParticleSystem function awake(obj) print("awake") Time.timeScale = 1 player = obj ui = player.transform : Find('UI').gameObject head = player.transform : Find('Head').gameObject body = player.transform : Find('Body').gameObject rigidbody = player : GetComponent('Rigidbody') particle = GameObject.Find('Particle') particle : GetComponent('ParticleSystem') : Stop() --相機相對角色位置 cameraRelativePosition = Camera.main.transform.position - player.transform.position --呼叫C#類 LuaBoxControl = CS.XLuaTest.LuaBoxControl end
五 效能效率測試
引用大佬技術貼