简单原理
ToLua 框架主要是通过静态绑定来实现 C# 与 Lua 之间的交互的,通过建立一个 Lua 虚拟机来映射 C# 脚本,然后再通过这个虚拟机来运行 Lua 脚本,Lua 脚本在运行时可以通过虚拟机反过来调用 C# 脚本里注册过的物体,虚拟机变相地实现了一个解释器的功能。
Lua在游戏开发中的作用
游戏或软件更新的时候
无需重新下载客户端安装
而是在应用程序启动的情况下
在内部进行的资源或者代码更新
修bug,更新等等
下载
地址:topameng/tolua: The fastest unity lua binding solution (github.com)
安装
导入之后点击 Lua -> Generate All 生成注册文件
在Tolua中,“Generate All” 主要执行以下操作:
- 读取之前定义的所有类型和函数,并生成适当的中间代码。
- 编译这些中间代码成为目标代码库(例如动态链接库或静态库),可以在C++和Lua之间进行交互。
- 根据预定义的规则,将生成的头文件和实现文件输出到指定的目录中,这些文件包含了 C++ 接口和实现的映射关系,以便在 C++ 代码中使用 Tolua 所生成的 Lua 函数和变量。
- 自动生成用于注册在 Lua 中使用的函数和变量的代码,包括初始化和清理函数。这些代码被包含在生成的头文件中,并可以在适当地时候由用户手动调用。
总体而言,“Generate All”所生成的内容包括:中间代码、目标代码库、头文件和实现文件、C++ 接口和实现的映射、用于注册在 Lua 中使用的函数和变量的代码。这些内容允许用户在 C++ 和 Lua 之间交互,简化了 C++ 和 Lua 代码之间的数据传输,提高了开发效率。
使用
C#调用Lua
实质上就是在利用Lua虚拟机调用Lua脚本
- 简单使用
//初始化一个 toLua解析器 (虚拟机)
LuaState luaState = new LuaState();
//启动解析器(虚拟机)
luaState.Start();
//执行lua代码
luaState.DoString("print('你好世界')");
//执行lua代码 并指明出处 方便调试时查看问题
luaState.DoString("print('你好世界')", "出处 xxx.cs");//执行代码块 如果之前有过 不会覆盖掉
//默认来说 加载路径为Lua文件夹下的路径 需要自定义可通过其他来重定向
//执行lua 文件 通过DoFile执行lua文件 可加可不加.lua后缀
luaState.DoFile("t"); //执行代码块 如果之前有过 会覆盖掉
//第二种执行lua文件的方法 不需要加lua后缀
luaState.Require("Main"); //加载代码块 并执行一次
//检查解析器栈顶是否为空
luaState.CheckTop();//CheckTop函数用来检查当前lua虚拟机的栈顶状态,如果栈中还有元素残留,说明虚拟机出现了问题
//销毁解析器
luaState.Dispose();
luaState = null;//置空
2 自定义Lua脚本位置
使用 DoFile 和 Require 方法时,要用 state.AddSearchPath(string fullPath) 手动给目标文件添加一个文件搜索位置
//第一种 如果该文件 属于 Lua文件夹下 那么可以直接加父目录
luaState.Require("t2");
//测试 新建文件夹的加载
luaState.AddSearchPath(Application.dataPath + "/MyLua");
//移除一个搜索路径 用的很少
luaState.RemoveSeachPath(Application.dataPath + "/MyLua");
luaState.Require("Leeson2_Loader2");
//第二种 使用LuaState中的方法 AddSearchPath
luaState.AddSearchPath(Application.dataPath + "/Lua/CSharpCallLua");
luaState.Require("t2");
3 调用变量
Luastate 类似于 Lua中的_G表
void Start()
{
LuaMgr.GetInstance().Init();
LuaMgr.GetInstance().Require("Main");
//获取全局变量
//得到luastate解析器 然后中括号 变量名 即可得到
Debug.Log("testNumber:" + LuaMgr.GetInstance().LuaState["testNumber"]);
Debug.Log("testBool:" + LuaMgr.GetInstance().LuaState["testBool"]);
Debug.Log("testFloat:" + LuaMgr.GetInstance().LuaState["testFloat"]);
Debug.Log("testString:" + LuaMgr.GetInstance().LuaState["testString"]);
//值拷贝
int value = Convert.ToInt32(LuaMgr.GetInstance().LuaState["testNumber"]);
value = 99;
Debug.Log("testNumber:" + LuaMgr.GetInstance().LuaState["testNumber"]);
//如果要改值 直接这样写即可
LuaMgr.GetInstance().LuaState["testNumber"] = 99;
Debug.Log("testNumber:" + LuaMgr.GetInstance().LuaState["testNumber"]);
//toLua中 也没有办法通过C#得到local申明的局部临时变量
Debug.Log("testLocal:" + LuaMgr.GetInstance().LuaState["testLocal"]);
//可以在C#处为lua添加全局变量 相当于在lua中的_G中加了一个变量
Debug.Log("addValue:" + LuaMgr.GetInstance().LuaState["addValue"]);
LuaMgr.GetInstance().LuaState["addValue"] = 999;
Debug.Log("addValue:" + LuaMgr.GetInstance().LuaState["addValue"]);
}
4 调用 lua方法
可以理解为Luastate.GetFunction 在Lua中的_G表中找
//无参无返回
//第一种方法 通过 GetFunction方法获取
LuaFunction function = LuaMgr.GetInstance().LuaState.GetFunction("testFun");
//调用 无参无返回
function.Call();
//执行完过后
function.Dispose();
//第二种方法 通过 中括号 函数名的形式
function = LuaMgr.GetInstance().LuaState["testFun"] as LuaFunction;
function.Call();
function.Dispose();
//第三种方式 转为委托来使用
//首先得到一个luafunction 然后再转成委托的形式
function = LuaMgr.GetInstance().LuaState.GetFunction("testFun");
//通过luafunction中的方法 存入到委托中再使用
UnityAction action = function.ToDelegate<UnityAction>();
action();
function.Dispose();
其他的关于有参,有返回的 Invoke函数基本上都能解决
//最后一个泛型类型 是返回值类型 前面的 是参数类型 依次往后排
result = function.Invoke<int, int>(199);
Debug.Log("有参有返回值 Invoke:" + result);
//部分源码
public R1 Invoke<R1>()
{
BeginPCall();
PCall();
R1 ret1 = CheckValue<R1>();
EndPCall();
return ret1;
}
public R1 Invoke<T1, R1>(T1 arg1)
{
BeginPCall();
PushGeneric(arg1);
PCall();
R1 ret1 = CheckValue<R1>();
EndPCall();
return ret1;
}
public R1 Invoke<T1, T2, R1>(T1 arg1, T2 arg2)
{
BeginPCall();
PushGeneric(arg1);
PushGeneric(arg2);
PCall();
R1 ret1 = CheckValue<R1>();
EndPCall();
return ret1;
}
等等
Lua调用C#
等等
总结
以上是简单介绍一下关于Tolua的安装和简单的使用 学习Tolua首先要对Lua语言有过学习理解
想要完整的使用 还需要至少去系统仔细的学习一下内容
C#调用Lua
- 如何在C#中调用Lua中table表现的List和Dictionary
- 如何在C#调用lua中的自定义table
- 如何在C#调用lua中的协程
- 如何去重新定义 解析lua的方式
Lua调用C#
等等内容