XLua 学习之路(一)

一、XLua背景

       xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,因其良好性能、易用性、扩展性而广受好评。现在,腾讯已经将xLua开源到GitHub。想了解的,可以点击这里Xlua下载。

二、在Unity中导入XLua

       首先,将上述的Xlua ZIP下载下来,然后打开xLua-master.zip包,你会看到一个Assets目录,这目录就对应Unity工程的Assets目录,保持这目录结构放到你的Unity工程即可。显然,这与导入一个Unity插件很类似。导入成功后,你的菜单栏里面会多一个XLua的功能。

三、Unity中加载Lua文件

       Unity有两种方式加载Lua文件:1.使用Unity动态加载的方式获取lua文件 2.用lua的require函数。
       首先,将要读取的Lua文件(比如:test.lua)放在Resources文件夹下(没有Resources文件夹的话,就自己创建一个);然后,将要读取的Lua文件的后缀名修改为(比如:test.lua.txt)。此处一定要修改成txt结尾的,否则就会读取不出来。(后面会进行解释);最后,在Unity创建脚本文件HelloWorldTest.cs,代码示例如下:

using UnityEngine;
using XLua;

public class HelloWorldTest : MonoBehaviour {

    //通过字符串的方式加载lua文件
    void Start () {
        LuaEnv env = new LuaEnv();//创建一个lua虚拟机
        //第一种 使用Unity动态加载的方式获取lua文件
        Debug.Log("第一种加载方式:");
        TextAsset ta = Resources.Load("test.lua");
        env.DoString(ta.ToString());

        //第二种
        //使用lua的require函数来获取lua文件
        //require实际上是调一个个的loader去加载
        //有一个成功就不再往下尝试,全失败则报文件找不到。
        Debug.Log("第二种加载方式:");
        env.DoString("require 'test'"); //加载test.lua.txt文件
        env.Dispose();//释放lua虚拟机
    }
}

       在采用第一种方式实现,在Unity中获取Lua文件时,采用的是动态加载的方式,指定的类型是TextAsset类型,此时,只能加载后缀为.txt的文件,因此,需要将lua文件的后缀进一步扩展成.txt。第二种,使用使用lua的require函数,用法看上面具体实现实现即可。require实际上是调一个个的loader去加载,下面将介绍一下自定义Loader如何加载Lua文件。

四、自定义Loader(CustomLoader)的实现

       在XLua中,提供了一个接口,让我们实现自定义Loader。接口如下:

public delegate byte[] CustomLoader(ref string filepath);
public void LuaEnv.AddLoader(CustomLoader loader)

       通过AddLoader可以注册个回调,该回调参数是字符串,lua代码里头调用require时,参数将会透传给回调,回调中就可以根据这个参数去加载指定文件,如果需要支持调试,需要把filepath修改为真实路径传出。该回调返回值是一个byte数组,如果为空表示该loader找不到,否则则为lua文件的内容。依旧读取上述Resources文件夹下test.lua.txt文件,该文件内容只有一条“print(“Hello World!”)”语句。此时执行的不是Resources文件夹下test.lua.txt文件(Hello World!没有被输出),而是执行了自定义Loader里更新的Lua文件(输出123)。测试示例代码如下:

using UnityEngine;
using XLua;
using System.Text;

public class CustomLoaderTest : MonoBehaviour {

    // 自定义loader
    void Start() {
        LuaEnv env = new LuaEnv();

        //添加自定义loader
        env.AddLoader(MyCustomLoader);

        //当自定义了MyCustomLoader的loader之后,由于更新了lua程序,源lua文件中的语句不被执行;
        //因为该loader被找到了,不再继续往下找
        env.DoString("require 'test'"); //此时,输出的不是Hello World!,而是123 

        env.Dispose();
    }

    //自定义loader
    private byte[] MyCustomLoader(ref string filePath)
    {
        //Debug.Log(filePath); //输出 test
        string s = "print(123)"; //更新的lua程序
        return Encoding.UTF8.GetBytes(s); //将lua文件转换为Bytes数组进行读取
    }
}

       另外,再看下,如何使用自定义的Loader加载Lua文件。首先,创建StreamingAssets文件夹,用于存放要读取的lua文件。然后,将lua文件的后缀扩展成.txt(比如:test007.lua.txt)。最后,创建Unity脚本CustomLoadLuaTest.cs,示例代码如下:

using UnityEngine;
using XLua;
using System.Text;
using System.IO;
public class CustomLoadLuaTest : MonoBehaviour {

    //通过读取文件的方式加载lua文件
    void Start () {
        LuaEnv env = new LuaEnv();

        //添加自定义loader
        env.AddLoader(MyCustomLoader);

        env.DoString("require 'test007'"); //输出 Hello World!

        env.Dispose();
    }

    //自定义loader
    private byte[] MyCustomLoader(ref string filePath)
    {
        //第一种:将Lua文件Resources文件加下
        //需要将Lua文件的相对路径拼出来
        //string path = ".\\Assets\\Test\\Resources\\" + filePath + ".lua.txt";
        //return Encoding.UTF8.GetBytes(File.ReadAllText(path));

        //第二种:将Lua文件放置在StreamingAssets文件夹下
        //Application.streamingAssetsPath获取StreamingAssets文件夹的目录地址
        string absPath = Application.streamingAssetsPath + "/" + filePath + ".lua.txt";
        return Encoding.UTF8.GetBytes(File.ReadAllText(absPath)); //读取lua文件
    }
}

因此,若采用自定义Loader加载Lua文件时,优先采用第二种方式来进行获取。

你可能感兴趣的:(XLua)