Skip to main content
Version: 2022.1

xLua 的集成

xLua 是腾讯开源的项目,根据官方的说明 xLua 为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用。为什么使用 xLua?其实 tolua 除了初始化扯犊子外,其他各方面比 xLua 纯粹实用。所以如果选择 xLua 需要把 tolua 和 xLua 结合使用,具体怎么用,可以参考两个项目的官方文档说明。

如何把 xLua 集成到使用 xasset 的项目里面呢?请参考以下步骤:

  1. 根据 xLua 的官方文档,把 xLua 下载到项目中。

  2. 修改生成代码的配置,按需把 lua 中会用到的 xasset 的运行时 API 配置到 LuaCallCSharp 的列表中,并把在 lua 中会用的回调配置到 CSharpCallLua 的列表中。例如:

    public static class GenCodeConfig
    {
    //lua中要使用到C#库的配置,比如C#标准库,或者Unity API,第三方库等。
    [LuaCallCSharp]
    public static List<Type> LuaCallCSharp = new List<Type>() {
    // 这里省略的其他配置
    // xasset-begin
    typeof(Versions),
    // loadables
    typeof(Asset),
    typeof(Scene),
    typeof(RawAsset),
    // operations
    typeof(Operation),
    typeof(InitializeVersions),
    typeof(CheckUpdate),
    typeof(DownloadFiles),
    typeof(InstantiateObject),
    typeof(GetDownloadSize),
    typeof(ClearFiles),
    // others
    typeof(Updater),
    typeof(Download),
    typeof(List<ManifestBundle>),
    typeof(List<DownloadInfo>),
    // xasset-end
    };

    //C#静态调用Lua的配置(包括事件的原型),仅可以配delegate,interface
    [CSharpCallLua]
    public static List<Type> CSharpCallLua = new List<Type>() {
    // 这里省略的其他配置
    // xasset - began
    typeof(Action<Asset>),
    typeof(Action<Scene>),
    typeof(Action<Operation>),
    typeof(Action<DownloadVersions>),
    // xasset - end
    };
    }
  3. 根据 xasset 的代码运行模式,在初始化的时候为 xLua 实现不同的自定义加载器,例如:

    public class Lua : MonoBehaviour
    {
    private readonly LuaEnv _env = new LuaEnv();
    private void Start()
    {
    if (Versions.SimulationMode)
    {
    _env.AddLoader(SimulationLoader);
    }
    else
    {
    _env.AddLoader(RuntimeLoader);
    }
    _env.DoString("require 'main'");
    }

    private static string GetLuaPath(ref string filepath)
    {
    // 假设 Lua 文件全部放在 Assets/Lua 目录下
    var path = $"Assets/Lua/{filepath}.txt";
    return path;
    }

    private static boolean TryToLoadBytesWithResources(ref string filepath, out byte[] bytes)
    {
    if (filepath == "main")
    {
    // 用 Resources 加载 main.lua,方便把 xasset 的初始化代码放到 lua 中。
    var asset = Resources.Load<TextAsset>("main");
    bytes = asset.bytes;
    return true;
    }
    return false;
    }

    private static byte[] RuntimeLoader(ref string filepath)
    {
    if (TryToLoadBytesWithResources(ref filepath, out var value))
    {
    return value;
    }
    var path = GetLuaPath(ref filepath);
    var asset = Asset.Load(path, typeof(TextAsset));
    var text = asset.asset as TextAsset;
    return text == null ? null : text.bytes;
    }

    private static byte[] SimulationLoader(ref string filepath)
    {
    if (TryToLoadBytesWithResources(ref filepath, out var value))
    {
    return value;
    }
    var path = GetLuaPath(ref filepath);
    return ! File.Exists(path) ? null : File.ReadAllBytes(path);
    }
    }
  4. 实现 main.lua 可以放到任意 Resources 文件夹下,例如:

    local Versions = CS.xasset.Versions
    local Scene = CS.xasset.Scene
    local startupScene = "Splash" -- 这里使用了自定义加载路径
    local function Initialize()
    local oper = Versions.InitializeAsync()
    oper.completed = function(op)
    if op.error == nil or op.error == "" then
    print("InitializeAsync completed")
    else
    print("InitializeAsync failed")
    end
    Scene.LoadAsync(startupScene)
    end
    end

    Initialize()
  5. 祝贺!你已经成功实现了 xLua 的集成。

提示

对于其他 lua 框架(tolua/slua)或非 lua 框架(ILRuntime/InjectFix/Puerts),其实基本都可以套用正交使用的原则照仿照这个来接入。