导入xlua
从github克隆xlua库复制Assets目录下的Plugins和XLua文件夹到自己的项目Assets目录下
C#调用Lua
lua解析器
// 0. 引用命名空间
using XLua;
// 1. 引入Lua解析器,以便在unity中执行lua
// 一般情况保持唯一
LuaEnv env = new LuaEnv();
//2. 执行lua语言
// 如果传入后两个参数在报错时会输出
env.DoString("print('hello world')"/*,文件信息,解释器信息*/);
// 一般执行lua脚本默认加载路径在Resources文件夹里
env.DoString("require('main')");
// 清除Lua中没有手动释放的对象 GC垃圾回收
// 一般在帧更新中定时执行,或者在切场景时执行
env.Tick();
// 销毁Lua解析器
env.Dispose();
lua文件加载重定向
void Start()
{
LuaEnv env = new LuaEnv();
// xlua提供的路径重定向方法
// 自定义加载lua文件的规则
// 当执行lua语言require时就会执行传入的这个自定义函数
env.AddLoader(MyCustomLoader);
env.DoString("require('lesson_2')");
}
// 这个自定义函数内找不到lua文件再去下一个自定义函数定义的路径找
// 最后去默认路径即Resources路径找
// 自动调用传入的filePath就是require('main')执行的lua脚本文件名如果是main那filePath的值就是main
private byte[] MyCustomLoader(ref string filePath)
{
// 拼接lua文件所在路径
string path = Application.streamingAssetsPath + "/lua 1/" + filePath + ".lua";
if (File.Exists(path))
{ return File.ReadAllBytes(path);
} else
{
Debug.Log("重定向失败" + filePath);
}
return null;
}
lua解析器管理器
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
public class LuaMgr
{
private static LuaMgr instance;
private string path;
public static LuaMgr getInstance()
{ if (instance == null)
{ instance = new LuaMgr();
} return instance;
}
public LuaMgr init(string path = "/lua_1/")
{ if (env == null)
{ instance.env = new LuaEnv();
instance.path = path;
instance.env.AddLoader(MyCustomLoader);
instance.env.AddLoader(MyCustomABLoader);
}
return instance;
} private byte[] MyCustomLoader(ref string filePath)
{ // 拼接lua文件所在路径
string path = Application.streamingAssetsPath + this.path + filePath + ".lua";
if (File.Exists(path))
{ return File.ReadAllBytes(path);
} else
{
Debug.Log("重定向失败" + filePath);
}
return null;
} /// <summary>
/// 自定义xlua文件路径AB包加载规则
/// </summary>
/// <param name="filePath"></param> /// <returns></returns> private byte[] MyCustomABLoader(ref string filePath)
{ // 拼接lua文件所在路径
string path = Application.streamingAssetsPath + "/lua";
AssetBundle ab = AssetBundle.LoadFromFile(path);
TextAsset asset = ab.LoadAsset<TextAsset>(filePath + ".lua");
if (asset)
{ return asset.bytes;
} else
{
Debug.Log("重定向失败" + filePath);
} return null;
} /// <summary>
/// lua解析器
/// </summary>
private LuaEnv env;
/// <summary>
/// lua中的大G表
/// </summary>
public LuaTable global
{ get { return env.Global;
}
}
public void exec(string str,bool fileFlag = false)
{ if(!isEnvExist())
return;
env.DoString(fileFlag ? "require('"+str+"')" : str );
}
public void gc()
{ if(!isEnvExist())
return;
env.Tick();
}
public void destory()
{
if(!isEnvExist())
return;
env.Dispose();
env = null;
}
public bool isEnvExist()
{ if (env == null)
Debug.Log("解析器不存在");
return env != null;
}}
调用lua全局变量
// c#代码
LuaMgr luaMgr = LuaMgr.getInstance().init().exec("lesson4");
string hwStr = luaMgr.global.Get<string>("hwStr");
Debug.Log(hwStr);
// lua代码
-- c#访问lua中全局变量
hwStr = 'hello world';
LueEnv env = new LuaEnv();
env.Global.get<T>("lua中声明的变量名") // 获取全局变量
env.Global.set<T>() // 设置
// 这里get进行的是值拷贝不会改变lua中的值如果要改变lua中的值要用set
调用lua全局函数
using System;
using UnityEngine;
using UnityEngine.Events;
using XLua;
[CSharpCallLua]
public delegate int custom(int a); // 一个参数一个返回值
[CSharpCallLua]
public delegate int custom1(int a ,out int v1,out bool v2); // 多个返回值用out
[CSharpCallLua]
public delegate int custom2(int a,params object[] args); // 变长参数
public class Lesson_4 : MonoBehaviour
{
void Start()
{ LuaMgr luaMgr = LuaMgr.getInstance().init().exec("lesson4");
string hwStr = luaMgr.global.Get<string>("hwStr");
Debug.Log(hwStr);
Func<int,int> luaFunction = luaMgr.global.Get<Func<int, int>>("hwFun"); // 一个参数一个返回值还可以这么写
custom1 custom1 = luaMgr.global.Get<custom1>("hwFun"); // 多返回值或者变长参数
int i1;
bool b1; Debug.Log(custom1(10,out i1,out b1));
Debug.Log(luaFunction(10));;
}
}
[!warning] 注意
改完c#调用lua相关的代码要用xlua重新生成代码
lua表映射到C#的List和Dictionary
LuaTable luaTable = LuaMgr.getInstance().init().exec("lesson4").global;
// 相同类型列表
// lua list1 = {1,2,3,4,5}
List<int> ints = luaTable.Get<List<int>>("list1");
foreach (int i in ints)
{
Debug.Log(i);
}
Debug.Log("==================");
// 不同类型列表
//lua list2 = {1,'a',true}
List<object> objects = luaTable.Get<List<object>>("list2");
foreach (object o in objects)
{
Debug.Log(o);
}
Debug.Log("==================");
// 相同类型键,不同类型值
/*
lua dic1 = { ['id'] = 1, ['age'] = 18, ['name'] = 'test' } */Dictionary<string,object> dictionary = luaTable.Get<Dictionary<string, object>>("dic1");
foreach (string dictionaryKey in dictionary.Keys)
{
Debug.Log(dictionaryKey);
Debug.Log(dictionary[dictionaryKey]);
}
Debug.Log("==================");
// 不同键类型,不同值类型
/*
lua dic2 = { [false] = 1, ['age'] = 18, ['name'] = 'test' } */Dictionary<object,object> dictionary2 = luaTable.Get<Dictionary<object, object>>("dic2");
foreach (object dictionaryKey in dictionary2.Keys)
{
Debug.Log(dictionaryKey);
Debug.Log(dictionary2[dictionaryKey]);
}
lua表映射到类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using XLua;
public class testIntClass
{
public int testInt;
}
public class TableToClass
{
// 访问权限必须为公共,私有和保护没法赋值,变量名要和lua那边语音
// 成员变量数量不必跟lua相符可多可少,少了忽略,多了也不会赋值
public int testint;
public bool testbool;
// 成员方法用Action映射
public UnityAction testFun;
// 嵌套类也能正常赋值
public testIntClass testIntClass;
}
public class Lesson_6 : MonoBehaviour
{
void Start()
{ /*
lua class1 = { testint = 1; testbool = true; testFun = function () print("表映射到类")
end; testIntClass = { testInt = 7 } } */ LuaTable luaTable = LuaMgr.getInstance().init().exec("lesson4").global;
TableToClass tableToClass = luaTable.Get<TableToClass>("class1");
Debug.Log(tableToClass.testint);
tableToClass.testFun();
Debug.Log(tableToClass.testIntClass.testInt);
}}
lua表映射到接口
[!info] 提示
跟表到类差不多就是要在c#的接口上加[CSharpCallLua]然后用xLua生成代码
[!warning] 注意
只有映射到接口是引用拷贝对值修改会影响到lua中的值
lua表映射到LuaTable和LuaFunction不建议使用效率低
/*
lua class1 = {
testint = 1; testbool = true; testFun = function () print("表映射到类")
end; testIntClass = { testInt = 7 } } */LuaTable luaTable = LuaMgr.getInstance().init().exec("lesson4").global;
LuaTable table = luaTable.Get<LuaTable>("interface1");
int i = table.Get<int>("testint");
LuaFunction i = table.Get<LuaFunction>("testint");
Debug.Log(i);