boxmoe_header_banner_img

菜就多练喵

文章导读

[Unity][XLua]热更新11——Lua解析管理器


avatar
Ib_Mccf 2026年3月5日 11

使用单例模式实现lua解析管理器,保证lua解析器的唯一性,通过管理器来执行lua文件和lua脚本,通过自定义重定向方法来从Lua文件夹/AB包中获取lua文件。

*从AB包中加载lua文件,需要注意AB无法直接加载.lua文件,需要在.lua文件后缀加.txt,通过文本的形式加载。

using System.IO;
using UnityEngine;
using XLua;
/// <summary>
/// Lua解析器管理器
/// 提供唯一的Lua解析器
/// </summary>
public class LuaMgr : BaseManager<LuaMgr>
{
    /// <summary>
    /// 唯一的Lua解析器
    /// </summary>
    private LuaEnv luaEnv;
    /// <summary>
    /// lua的_G全局表
    /// </summary>
    public LuaTable Global
    {
        get =>  luaEnv.Global;
    }
    
    /// <summary>
    /// 初始化解析器
    /// </summary>
    public void Init()
    {
        //防止重复初始化
        if(luaEnv != null) return;
        luaEnv = new LuaEnv();
        //加载lua重定向
        luaEnv.AddLoader(MyCustomLoader);
        luaEnv.AddLoader(MyCustomABLoader);
    }   
    #region Lua重定向
    //自定义加载lua文件的规则
    private byte[] MyCustomLoader(ref string filePath)
    {
        //传入的参数是 require执行的lua脚本文件名
        string path = Application.dataPath + "/Lua/" + filePath + ".lua";
        //判断文件是否存在
        if (File.Exists(path))
        {
            return File.ReadAllBytes(path);
        }
        else
        {
            Debug.LogError("MyCustomLoader重定向Lua文件重定向失败:" + path);
        }
        return null;
    }
    /// <summary>
    /// 从AB包中加载lua文件
    /// </summary>
    /// <param name="filePath"></param>
    /// <returns></returns>
    private byte[] MyCustomABLoader(ref string filePath)
    {
        //AB包中只能加载.txt后缀的lua文件
        /*
        //加载AB包
        string path = Application.streamingAssetsPath + "/lua";
        AssetBundle ab = AssetBundle.LoadFromFile(path);
        //加载lua文件
        TextAsset textAsset = ab.LoadAsset<TextAsset>(filePath + ".lua");
        //返回lua文件的字节流
        return textAsset.bytes;
        */
        TextAsset lua = ABMgr.GetInstance().LoadRes<TextAsset>("lua",filePath + ".lua");
        if(lua == null)
        {
            Debug.LogError("MyCustomABLoader重定向Lua文件加载失败:" + filePath);
            return null;
        }
        return lua.bytes;
    }
    #endregion
    /// <summary>
    /// 传入lua文件名,执行lua脚本
    /// </summary>
    /// <param name="fileName"></param>
    public void DoLuaFile(string fileName)
    {
        string str = $"require('{fileName}')";
        DoString(str);  
    }
    
    /// <summary>
    /// 执行lua脚本
    /// </summary>
    /// <param name="str"></param>
    public void DoString(string str)
    {
        if(!CheckEnv())return;
        luaEnv.DoString(str);
    }
    
    /// <summary>
    /// 垃圾回收
    /// </summary>
    public void Tick()
    {
        if(!CheckEnv())return;
        luaEnv.Tick();
    }
    /// <summary>
    /// 销毁解析器
    /// </summary>
    public void Dispose()
    {
        if(!CheckEnv())return;
        luaEnv.Dispose();
        luaEnv = null;  
    }

    private bool CheckEnv()
    {
        if(luaEnv == null)
        {
            Debug.LogError("Lua解析器未初始化!");
            return false;
        }
        return true;
    }
}


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字

插入代码