兩者都是常見的基於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
五 性能效率測試
引用大佬技術貼
Unity中SLua、Tolua、XLua和ILRuntime效率評測
unity游戲熱更新方案比較(xlua tolua)
Lua文件的加載方面。xlua是AddLoader , tolua是AddSearchPath 不過xlua可以通過hotfix對c#中的代碼進行修改 主要是方便改bug(簡稱打補丁)而且官方文檔說GC性能問題有很大的提升 tolua不可以對C#中的代碼進行修改 但tolua多了AB打包類 以及其他的一些管理類