|
首先学习下LuaEnv类(Lua虚拟机,建议全局唯一)
- object[] DoString(string chunk, string chunkName = "chuck", LuaTable env = null)描述:
- 执行一个代码块。
- 参数:
- chunk: Lua代码;
- chunkName: 发生error时的debug显示信息中使用,指明某某代码块的某行错误;
- env :为这个代码块;
- 返回值:
- 代码块里return语句的返回值;
- 比如:return 1, “hello”,DoString返回将包含两个object, 一个是double类型的1, 一个是string类型的“hello”
- 例子:
- LuaEnv luaenv = new LuaEnv();
- object[] ret = luaenv.DoString("print(‘hello’)\r\nreturn 1")
- UnityEngine.Debug.Log("ret="+ret[0]);
- luaenv.Dispose()
- T LoadString<T>(string chunk, string chunkName = "chunk", LuaTable env = null)
- 描述:
- 加载一个代码块,但不执行,只返回类型可以指定为一个delegate或者一个LuaFunction
- 参数:
- chunk: Lua代码;
- chunkName: 发生error时的debug显示信息中使用,指明某某代码块的某行错误;
- env :为这个代码块;
- 返回值:
- 代表该代码块的delegate或者LuaFunction类;
- LuaTable Global;
- 描述:
- 代表lua全局环境的LuaTable
- void Tick()
- 描述:
- 清除Lua的未手动释放的LuaBase(比如,LuaTable, LuaFunction),以及其它一些事情。
- 需要定期调用,比如在MonoBehaviour的Update中调用。
- void AddLoader(CustomLoader loader)
- 描述:
- 增加一个自定义loader
- 参数:
- loader:就一个回调,其类型为delegate byte[] CustomLoader(ref string filepath),当一个文件被require时,这个loader会被回调,其参数是require的参数,如果该loader找到文件,可以将其读进内存,返回一个byte数组。如果需要支持调试的话,而filepath要设置成IDE能找到的路径(相对或者绝对都可以)
- void Dispose()
- 描述:
- Dispose该LuaEnv。
- LuaEnv的使用建议:全局就一个实例,并在Update中调用GC方法,完全不需要时调用Dispose
复制代码 示例代码: 执行字符串- using UnityEngine;
- using XLua;
- public class HelloWorld01 : MonoBehaviour {
- private LuaEnv luaenv;
- // Use this for initialization
- void Start () {
- luaenv = new LuaEnv();
- luaenv.DoString("print('Hello world!')"); //参数是lua程序,注意参数既要符合C#的语法规范(传字符串要加“”),又要符合lua语法规范
- luaenv.DoString(" CS.UnityEngine.Debug.Log('Hello world') "); //在Lua代码中调用C#代码,要有CS标识
- }
- /// <summary>
- /// 用完要记得释放
- /// </summary>
- private void OnDestroy()
- {
- luaenv.Dispose();
- }
- }
复制代码
2.从Lua源文件中读取Lua代码并运行
结构如下图:
首先创建Lua文件夹,并加上一个.txt后缀更改成文本格式,比如helloworld.lua.txt(注意后面的.txt):- print("Hello world from file")
- a=2
- b=3
- print(a+b)
复制代码 读取并运行文件中的Lua代码:- TextAsset ta = Resources.Load<TextAsset>("helloworld.lua"); // 加载 helloworld.lua.txt文本,注意加载.lua文件要加后缀
- LuaEnv env = new LuaEnv();
- env.DoString(ta.text);
- env.Dispose();
复制代码 3.通过内置的Loader加载lua源文件
用lua的require函数即可require实际上是调一个个的loader去加载,有一个成功就不再往下尝试,全失败则报文件找不到。目前xLua除了原生的loader外,还添加了从Resource加载的loader,需要注意的是因为Resource只支持有限的后缀,放Resources下的lua文件得加上txt后缀。建议的加载Lua脚本方式是:整个程序就一个DoString("require 'main'"),然后在main.lua加载其它脚本(类似lua脚本的命令行执行:lua main.lua)。
- LuaEnv env = new LuaEnv();
- //引入并执行Lua代码,是使用loader来加载helloworld.lua.txt,找到就会执行代码,没找到就会报错
- //要确保文件在Resources文件夹下,并保证文件名一致
- env.DoString("require 'helloworld'");
- env.Dispose();
复制代码 loader没有找到文件所报的错误:
4.自定义Loader
当lua脚本放在自定义目录下时使用内置loader时找不到的,因此需要自定义loader
- 在xLua加自定义loader是很简单的,只涉及到一个接口:
public delegate byte[] CustomLoader(ref string filepath);
public void LuaEnv.AddLoader(CustomLoader loader)
通过AddLoader可以注册个回调,该回调参数是字符串,lua代码里头调用require时,参数将会透传给回调,回调中就可以根据这个参数去加载指定文件,如果需要支持调试,需要把filepath修改为真实路径传出。该回调返回值是一个byte数组,如果为空表示该loader找不到,否则则为lua文件的内容。有了这个就简单了,用IIPS的IFS?没问题。写个loader调用IIPS的接口读文件内容即可。文件已经加密?没问题,自己写loader读取文件解密后返回即可
示例代码:- using UnityEngine;
- using XLua;
- using System.IO;
- public class CreateLoader : MonoBehaviour {
- void Start () {
- LuaEnv env = new LuaEnv();
- env.AddLoader(MyLoader);//参数是委托的方法名,其实是自定义方法
- //require时会将名字传递给每个loader查找,先执行我们自定义的loader,如果自定义loader返回不为空,则执行改代码,不会再执行内置的loader
- env.DoString("require 'test007'");
- env.Dispose();
- }
- private byte[] MyLoader(ref string filePath)
- {
- string absPath = Application.streamingAssetsPath + "/" + filePath + ".lua.txt";
- return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
- }
- }
复制代码 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|