1. 程式人生 > 其它 >Lua檔案載入

Lua檔案載入

XLua只是提供Lua在Unity上執行,並沒有提供熱更行解決方案。

Lua檔案載入

載入字串

直接使用luaEnv.DoString()執行一個字串,字串必須符合Lua語法

但載入字串這個方法不常用。

載入Lua檔案

用Lua的require函式。

DoString("require '檔案路徑(基於Resources資料夾)'")

使用require預設從Resources下進行載入(放Resources下的lua檔案得加上txt字尾)。

using UnityEngine;
using XLua;

public class Test : MonoBehaviour {
    // 建立一個Lua虛擬機器
    LuaEnv luaEnv = null;

    void Start() {
        // 生成了這個虛擬機器
        luaEnv = new LuaEnv();
        // 執行Lua語句
        luaEnv.DoString("print('Hello world')");
		// 執行byfile(Lua)檔案
        luaEnv.DoString("require 'byfile' ");
    }
    // XLua只是提供Lua在Unity上執行,並沒有提供熱更行解決方案。

    void Update() {
        if (luaEnv != null)
            // 定時清理記憶體,luaEnv有自己的垃圾回收機制。
            luaEnv.Tick();
    }

    void OnDestroy() {
        // 手動釋放掉
        luaEnv.Dispose();
    }
}

自定義載入器

使用require函式只能載入Resources檔案下的檔案,而Resources無法進行熱更新。這時就需要用於自定義載入器。

資源熱更新:

  • 伺服器:制定打包工具、制定打包策略、將需要上傳的資源上傳到資源伺服器。
  • 客戶端:下載清單檔案,對比hash值,一樣的話讀取本地,不一樣下載AB包替換本地資源,並重新整理hash值,提供資源管理器,根據資源路徑找到對應的AB包,提取AB包中的資源。

邏輯熱更新:

  • 邏輯熱更新依賴於資源熱更新,通過資源熱更新更新對應的lua指令碼內容,在LuaEnv呼叫之前,使用者通過AddLoader新增自定義的邏輯,在自定義的邏輯中使用資源管理器呼叫AB包中的資源,就能夠實現lua邏輯熱更新。
using UnityEngine;
using System.Collections;
using XLua;

namespace Tutorial
{
    public class CustomLoader : MonoBehaviour
    {
        LuaEnv luaenv = null;
        // Use this for initialization
        void Start()
        {
            luaenv = new LuaEnv();
            luaenv.AddLoader((ref string filename) =>
            {
                if (filename == "InMemory")
                {
                    string script = "return {ccc = 9999}";
                    return System.Text.Encoding.UTF8.GetBytes(script);
                }
                return null;
            });
            luaenv.DoString("print('InMemory.ccc=', require('InMemory').ccc)");
        }

        // Update is called once per frame
        void Update()
        {
            if (luaenv != null)
            {
                luaenv.Tick();
            }
        }

        void OnDestroy()
        {
            luaenv.Dispose();
        }
    }
}

Lua呼叫C#指令碼邏輯

// C#測試案例
using UnityEngine;
using XLua;

[LuaCallCSharp]
public class Weapon {
    public string name = "ailisi_dajian";
}

[LuaCallCSharp]
public class Hero {
    // 成員變數
    public string name = "ailisi";
    // 巢狀成員標量
    public Weapon weapon = new Weapon();

    public void cheng_yuan_fang_fa() {
        Debug.Log("C#:成員方法");
    }

    public static void jing_tai_fang_fa() {
        Debug.Log("C#:靜態方法");
    }


    public string duo_fan_hui_zhi_fang_fa(ref string str) {
        return "return";
    }

}

// 防止在真機執行時lua不能呼叫C#
[LuaCallCSharp]
public class Warrior : Hero {
    public float Attack = 10;
}
// C#載入Lua檔案
using UnityEngine;
using XLua;

public class DOLua : MonoBehaviour {
    public TextAsset lua;
    public LuaEnv luaEnv = null;
    void Start() {
        luaEnv = new LuaEnv();
        // 使用Xlua預設載入Lua指令碼,需要放到Resources下
        luaEnv.DoString(lua.text);
    }

    void Update() {
        if (luaEnv != null)
            luaEnv.Tick();
    }

    void OnDestroy() {
        luaEnv.Dispose();
    }
}
-- Lua呼叫UnityAPI的時候每次都必須以CS開頭,可以先在一個公共類中將頻繁呼叫的型別宣告出來
UnityEngine = CS.UnityEngine
GameObject = UnityEngine.GameObject
Transform = UnityEngine.Transform
Debug = UnityEngine.Debug
Hero = CS.Hero
Warrior = CS.Warrior
// Lua呼叫C#中的邏輯
-- 引入common公共類
require("common")

-- 建立一個GameObject
local obj = GameObject()
-- 改變GameObject名字
obj.name = "LuaCreateObj"

-- 例項化一個角色
local hero = Hero()

-- 輸出角色名字
print(hero.name)
-- 輸出角色武器名字
print(hero.weapon.name)
-- 使用:呼叫成員方法
hero:cheng_yuan_fang_fa()
-- 使用.呼叫靜態方法
Hero.jing_tai_fang_fa()

local str ="str"
-- 多返回值成員方法
local a,b = hero:duo_fan_hui_zhi_fang_fa(str)
print(a,b)

-- 例項化一個戰士
local warrior = Warrior()
-- 輸出繼承父類的成員變數
print(warrior.name)

XLua 配置

防止在真機情況下lua不能呼叫C#邏輯。

  • 打標籤:使用者自定義的型別可以進行打標籤,系統api無法進行打標籤(該方式方便,但在il2cpp下會增加不少程式碼,不建議使用)。

    [LuaCallCSharp]
    public class A{
    
    }
    
  • 靜態列表:對於沒法打標籤的型別,這時可以在一個靜態類裡宣告一個靜態欄位(下面是XLua框架中新增靜態列表的指令碼)。找到專案中ExampleGenConfig檔案在裡面新增指定的型別即可。

  • 動態列表