xLua 的集成
xLua 是腾讯开源的项目,根据官方的说明 xLua 为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用。为什么使用 xLua?其实 tolua 除了初始化扯犊子外,其他各方面比 xLua 纯粹实用。所以如果选择 xLua 需要把 tolua 和 xLua 结合使用,具体怎么用,可以参考两个项目的官方文档说明。
如何把 xLua 集成到使用 xasset 的项目里面呢?请参考以下步骤:
根据 xLua 的官方文档,把 xLua 下载到项目中。
修改生成代码的配置,按需把 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
};
}根据 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);
}
}实现 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()祝贺!你已经成功实现了 xLua 的集成。
提示
对于其他 lua 框架(tolua/slua)或非 lua 框架(ILRuntime/InjectFix/Puerts),其实基本都可以套用正交使用的原则照仿照这个来接入。