toLua與Xlua使用方法總結


兩者都是常見的基於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打包類 以及其他的一些管理類


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM