找回密码
 立即注册
查看: 284|回复: 0

xlua初步研究

[复制链接]
发表于 2021-8-12 21:18 | 显示全部楼层 |阅读模式
Xlua学习笔记
1.什么是xlua?
Xlua是一个支持unity和lua进行相互调用的插件
2.如何运行加载Lua的源文件
(1).我们创建一个Resources文件夹,用来存放lua源文件,这里我们
写一些比较简单的lua代码,这里命名我们用helloWorld.lua.txt来命名,我们用txt类型来读取,但是又表明它是一个Lua文件
a=2

b=3

print(a+b)
(2)然后我们在c#中用Resource来进去读取
1.我们用TextAsset来接收这个类型的数据
2. 然后我们创建一个LuaEnv的虚拟机
3.用DoString方法来加载这个文件
4.释放这个环境
usingSystem.Collections;

usingSystem.Collections.Generic;

usingUnityEngine;

using XLua;

publicclassHelloWorld2 : MonoBehaviour {


// Use this for initialization

void Start () {

TextAsset ta= Resources.Load<TextAsset>("helloWorld.lua");//我们可以通过这个来加载text类型的lua文件

LuaEnv env=newLuaEnv();

env.DoString(ta.text);

env.Dispose();

}


}
3.如何加载我们自定义的lua程序
首先我们要创建自己的lua环境
然后我们定义一个返回字节类型的Loader
然后我们在Start里通过AddLoader进行调用就可以加载这个Loader了
如果这个Loader被执行,就不会调用系统内置的Resource里的那个Loader
Require会依次调用每个loader直到某个loader给它返回一个值
publicclassHelloWorld2 : MonoBehaviour {


// Use this for initialization

void Start () {

//这样我们就添加了一个自定义的loader

LuaEnv env= new LuaEnv();

env.AddLoader(MyLoader);

env.DoString("require'helloWorld'");

env.Dispose();

}


4.// Update is calledonce per frame

5.void Update () {

6.

7.}

8.privatebyte[] MyLoader(refstring filepath)

9.{

10.string s = "print(123)";

11.returnSystem.Text.Encoding.UTF8.GetBytes(s);

12.

13.}

14.}
4.如何用自定义Loader加载文件夹内的lua文件
首先我们创建一个StreamingAssets的文件夹,并且在里面创建一个007.lua.txt的文件
然后我们创建luaEnv环境并且引入Io数据流对文件进行读取
然后我们用Application.StreamingAssets来获得文件路径
再用file.readAllText来进行读取,最后返回字节类型数据
再用env.addLoader进行调用,用Dostring来require这个文件即可
usingSystem.Collections;

usingSystem.Collections.Generic;

usingUnityEngine;

using XLua;

usingSystem.IO;

publicclassHelloWorld2 : MonoBehaviour {


// Use this for initialization

void Start () {

//这样我们就添加了一个自定义的loader

LuaEnv env = newLuaEnv();

env.AddLoader(MyLoader);

env.DoString("require '007'");

env.Dispose();

}


// Update is called once per frame

void Update () {


}

privatebyte[] MyLoader(refstring filepath)

{


string path =Application.streamingAssetsPath + "/" + filepath + ".lua.txt";

File.ReadAllText(path);

returnSystem.Text.Encoding.UTF8.GetBytes(File.ReadAllText(path));


}

}
5.我们如何访问到lua里面定义的全局变量
假设我在lua里面定义了一个
Int a=10;
然后我想要从获取到这个变量,可以使用
LuaEnv env=newLuaEnv();
env.Global.Get<int>("a");
这里我们接受类型必须和lua中定义的类型一样,并且变量名也一样,这样就可以接受到这个变量值了
6.我们如何访问lua中的table呢?
这里介绍一个比较耗费性能的方法
首先我们在lua文件里定义一个Person={name=wenxue,age=23}
然后我们在c#文件里定义一个对应的映射来接受
Class Person{
Public string name;
Public int age;
}
然后start里调用env.gloabal.get就可以获取到这个表了
LuaEnv env=new LuaEnv();
Env.Gloabal.get<Person>(person);
Print(p.name+p.age);
这个方法本质上是将lua中的数据复制过来,因此会比较耗费性能
7.如何通过InterFace来访问lua文件
首先,我们要定义一个接口,来接受lua文件
//这里的话我们通过接口来访问lua中的属性和方法

[CSharpCallLua]//这个特性是用来让接口和Lua文件连接

interfaceIPerson

{

string name { get; set; }

string age { get; set; }

void eat(int a,int b);

}
这里是lua文件
person=

{

name="wenxue",age=23,

eat=function(self,a,b)

print(a+b)

end

}
接口中的属性和方法名要和lua中的相对应,但是在lua中的函数和c#不同,lua中的函数第一个参数代表自身,需要在lua文件中用self指定
然后我们就可以在start方法里用DoString加载对应lua文件
用Gloabal.Get接收到对应的接口
LuaEnv env = newLuaEnv();

env.DoString("require 'helloWorld'");

IPerson p= env.Global.Get<IPerson>("person");

print(p.name + p.age);

p.eat( 12, 34);



env.Dispose();
这里接口的话就不需要和定义类一样复制数值,还是提供一个通道,并且接口获得的数值我们可以在c#里面自行修改
8.通过dictionary和list来访问lua中的数值
这两个一个是获得其中的键值对,一个是获得单个的数值,组合起来可以用来访问我们需要的信息
Dictionary<string, object> dic =env.Global.Get<Dictionary<string, object>>("person");//这个是通过字典来获得lua中的数据

foreach (string key in dic.Keys)

{

print(key);

}


List<object>list = env.Global.Get<List<object>>("person");

foreach (var o in list)

{

print(o);

}
9.通过LuaTable来获得数值
这种方式也可以获得带键的数值,但是不带键的就不方便获取到了
LuaTable table = env.Global.Get<LuaTable>("person");

print(table.Get<string>("name"));
10,通过委托的方式来获得lua中的全局函数
首先我在lua里定义这样一个函数
function add(a,b)

print(a+b)

returna+b

end
然后的话我们定义这样一个委托,和lua中的函数相对应

[CSharpCallLua]

delegateintAdd(int a, int b);
然后我们在Start里对这个委托进行调用,这样就可以获得到这个函数了,当然委托调用完要记得释放这个委托
Add add = env.Global.Get<Add>("add");

int res =add(12, 23);

print(res);

add = null;



env.Dispose();
这里的话如果lua那边的函数是返回多个值,我们c#里面的委托接受后面的值就可以用ref或者out修饰的参数进行接受
11.LuaFunction访问lua中的函数
这种也可以访问lua中的函数,但是比较消耗性能,这里我们获得add函数厚调用其中的call方法,传递参数,就可以实现这个函数了,但是这个我们一般是在游戏初始化的时候才会用到
LuaFunction lfc =env.Global.Get<LuaFunction>("add");

object[]os=lfc.Call(2, 3);

foreach (object o in os)

{

print(o);

}
12.如何在lua中调用c#文件
首先我们还是访问这个Lua文件
void Start() {

LuaEnv env = newLuaEnv();

env.DoString("require 'cSharpCallLua'");

env.Dispose();


}
然后我们用这个代码就可以调用c#文件创建unity里的游戏物体了
CS.UnityEngine.GameObject()
这里lua中代码区别1.lua里没有new关键字2.lua中所有相关c#的代码都是要用CS.来修饰
这里调用其它静态属性和方法也是这么写,如果是重复调用的变量,我们可以先声明
例如:localgameobject=CS.UnityEngine.GameObject;
这样的话,后面我们要调用gameObject就不需要重复声明了
调用成员方法用冒号就可以进行传递
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 08:57 , Processed in 0.123916 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表