Lua檔案載入
阿新 • • 發佈:2022-12-08
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
檔案在裡面新增指定的型別即可。 -
動態列表