Xlua学习笔记整理。还有很多没整理完,慢慢来。
文章目录
一.Xlua中Lua文件加载的两种方式
1.直接执行字符串:
LuaEnv env = new LuaEnv();
env.DoString("print('这是我的第一个lua程序'");
2.加载Lua文件
使用Require函数加载Lua文件
require就是一个个的调用Loader,查找出匹配的lua文件,然后执行该文件。
(1)使用默认Loader加载
LuaEnv env = new LuaEnv();
env.DoString("require 'SimpleLua' ");//不用加lua后缀
(2)使用自定义Loader加载
通过Addloader可以注册个回调,该回调参数是字符串,Lua代码里头调用require时,参数将会自动传给回调,
回调中就可以根据这个参数去加载指定文件,如果需要支持调试,需要把filepath修改为真实路径传出。
LuaEnv env = new LuaEnv();
env.AddLoader(CustomMyLoader);
env.DoString("require 'HelloWord'");
/// <summary>
/// 定义回调方法
/// 功能:
/// 本方法主要功能是自定义lua文件路径
/// </summary>
/// <param name="fileName">文件名称</param>
/// <returns></returns>
private byte[] CustomMyLoader(ref string fileName)
{
byte[] byArrayReturn = null;//返回数据
//定义lua路径
string luaPath = Application.dataPath + "/StreamingAssets/" + fileName + ".lua";
//读取lua路径中指定lua文件内容
string strLuaContent =File.ReadAllText(luaPath);
//数据类型转换
byArrayReturn = System.Text.Encoding.UTF8.GetBytes(strLuaContent);
return byArrayReturn;
}
注意:
1.使用默认Loader加载lua文件,必须放在Resources特殊目录下,否则查找不到无法加载。
2.因为Resource只支持有限的后缀,放Resource下的lua文件需要加上txt后缀。
3.自定义Loader可以进一步扩展加载路径,可以按照自己的方式进行加载lua与执行lua代码。
4.require本质是按照既定的查找顺序,找到需要的lua程序,否则返回nil,然后报错。
二.CsharpCallLua
主要是C#调用Lua的全局数据类型,包括字段,table,函数。
最大特点: env.Global.Get调用lua中的表,字段,函数。
---- 1.全局字段
访问LuaEnv.Global就可以了,上面有个模版Get方法,可指定返回的类型。
eg:
Lua
str="全局变量"
number=10
C#
string str1 = env.Global.Get<string>("str");//字符串类型
int number = env.Global.Get<int>("number");//数字类型
---- 2.全局table
由于Lua中Table可以充当很多职能,如数组,字典(键值对),类(Class)。根据其职能不同调用也不同。
-------- (1).table为数组时
直接映射到List
eg:
Lua
progamLanguage={"C#","Lua","C++","C"}
C#
List<object> listGameLan = env.Global.Get<List<object>>("progamLanguage");
-------- (2).table为字典时(键值对)
直接映射到Dictionary<string, object>
eg:
Lua
gameLanguage={str1="C#语言",str2="lua语言",str3="C++语言",str4="C语言"}
C#
Dictionary<string, object> dicGameLan = env.Global.Get<Dictionary<string, object>>("gameLanguage");
-------- (3).table为类时(Class)
当Lua中的table为类时有三种调用方法,一种是映射到普通class或struct,为值拷贝。一种是映射到接口interface,是引用拷贝。一种是映射到Xlua自身的LuaTable上。
Lua
--定义一个综合表(lua中的oop思想)
GameUser=
{
name="小河",
age=199,
ID="188875221",
Speak=function()
print("lua玩家在讨论中")
end,
Walking=function()
print("lua玩家在健身中")
end,
Calulation=function(this,num1,num2) --说明:this 这里命名可以任意,表示当前对象(即GameUser)
print("lua玩家加年龄和")
return this.age+num1+num2
end
}
----------------- 1)映射到class,值拷贝
定义一个class,有对应table的字段的public属性,而且有无参数构造函数即可。table的属性可以多于或者少于class的属性,可以嵌套其他复杂类型。
eg:
C#
public class GameUser
{
public string name;
public int age;
public int ID;
public void Speak()
{
}
public void Walking()
{
}
public int Calulation(int num1, int num2)
{
return 0;
}
}
public class CsharpCallLuaTableByClass : MonoBehaviour
{
//lua环境(官方建议全局唯一)
LuaEnv env = null;
private void Start()
{
env = new LuaEnv();
//不用加lua后缀
env.DoString("require 'CsharpCallLuaTable' ");
//**********************************************************************************
//方式1: 使用class(struct)来映射得到lua中的table内容。
//值得注意的是,这个过程是值拷贝,如果class比较复杂代价会比较大。(即:较消耗性能)
//而且修改class的字段值不会同步到table,反过来也不会。此种方式可以通过把类型加到
//GCPotimize生成减低开销。
//得到lua中的表信息
GameUser gameuser = env.Global.Get<GameUser>("GameUser");
Debug.Log("GameUser.name=" + gameuser.name);
Debug.Log("GameUser.age="+gameuser.age);
Debug.Log("GameUser.ID="+gameuser.ID);
gameuser.Walking();//调不出来
gameuser.Speak();//调不出来
Debug.Log(gameuser.Calulation(50, 30));//调不出来,值为0
}
性能分析:
这个过程是值拷贝,修改Class的字段值不会同步到Lua中的table。如果class比较复杂代价会比较大(即:较消耗性能。)而且修改class的字段值不会同步到table,反过来也不会。此种方式可以通过把类型加到GCPotimize生成减低开销。
这里