xlua初步研究

Xlua学习笔记

1.    什么是xlua?

Xlua是一个支持unitylua进行相互调用的插件

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;

public class HelloWorld2 : 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给它返回一个值

public class HelloWorld2 : 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.      private byte[] MyLoader(ref string 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进行调用,用Dostringrequire这个文件即可

usingSystem.Collections;

usingSystem.Collections.Generic;

usingUnityEngine;

using XLua;

usingSystem.IO;

public class HelloWorld2 : 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 () {

       

    }

   private byte[] MyLoader(ref string 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文件连接

    interface IPerson

   {

       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.通过dictionarylist来访问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]

    delegate int Add(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就不需要重复声明了

调用成员方法用冒号就可以进行传递

 

猜你喜欢

转载自blog.csdn.net/qq_36574586/article/details/78384980
今日推荐