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

xLua学习之路(二) ------ 通过xLua 虚拟机运行lua程序(包括lua代码/lua脚本)

[复制链接]
发表于 2021-8-13 11:28 | 显示全部楼层 |阅读模式
    首先学习下LuaEnv类(Lua虚拟机,建议全局唯一)
  1. object[] DoString(string chunk, string chunkName = "chuck", LuaTable env = null)描述:
  2. 执行一个代码块。
  3. 参数:
  4. chunk: Lua代码;
  5. chunkName: 发生error时的debug显示信息中使用,指明某某代码块的某行错误;
  6. env :为这个代码块;
  7. 返回值:
  8. 代码块里return语句的返回值;
  9. 比如:return 1, “hello”,DoString返回将包含两个object, 一个是double类型的1, 一个是string类型的“hello”
  10. 例子:
  11.         LuaEnv luaenv = new LuaEnv();
  12.         object[] ret = luaenv.DoString("print(‘hello’)\r\nreturn 1")
  13.         UnityEngine.Debug.Log("ret="+ret[0]);
  14.         luaenv.Dispose()
  15. T LoadString<T>(string chunk, string chunkName = "chunk", LuaTable env = null)
  16. 描述:
  17. 加载一个代码块,但不执行,只返回类型可以指定为一个delegate或者一个LuaFunction
  18. 参数:
  19. chunk: Lua代码;
  20. chunkName: 发生error时的debug显示信息中使用,指明某某代码块的某行错误;
  21. env :为这个代码块;
  22. 返回值:
  23. 代表该代码块的delegate或者LuaFunction类;
  24. LuaTable Global;
  25. 描述:
  26. 代表lua全局环境的LuaTable
  27. void Tick()
  28. 描述:
  29. 清除Lua的未手动释放的LuaBase(比如,LuaTable, LuaFunction),以及其它一些事情。
  30. 需要定期调用,比如在MonoBehaviour的Update中调用。
  31. void AddLoader(CustomLoader loader)
  32. 描述:
  33. 增加一个自定义loader
  34. 参数:
  35. loader:就一个回调,其类型为delegate byte[] CustomLoader(ref string filepath),当一个文件被require时,这个loader会被回调,其参数是require的参数,如果该loader找到文件,可以将其读进内存,返回一个byte数组。如果需要支持调试的话,而filepath要设置成IDE能找到的路径(相对或者绝对都可以)
  36. void Dispose()
  37. 描述:
  38. Dispose该LuaEnv。
  39. LuaEnv的使用建议:全局就一个实例,并在Update中调用GC方法,完全不需要时调用Dispose
复制代码
示例代码:  执行字符串
  1. using UnityEngine;
  2. using XLua;
  3. public class HelloWorld01 : MonoBehaviour {
  4.     private LuaEnv luaenv;
  5.     // Use this for initialization
  6.     void Start () {
  7.         luaenv = new LuaEnv();
  8.         luaenv.DoString("print('Hello world!')");  //参数是lua程序,注意参数既要符合C#的语法规范(传字符串要加“”),又要符合lua语法规范
  9.         luaenv.DoString(" CS.UnityEngine.Debug.Log('Hello world') "); //在Lua代码中调用C#代码,要有CS标识
  10.         }
  11.     /// <summary>
  12.     /// 用完要记得释放
  13.     /// </summary>
  14.     private void OnDestroy()
  15.     {
  16.         luaenv.Dispose();
  17.     }
  18. }
复制代码


  2.从Lua源文件中读取Lua代码并运行

        结构如下图:                                 


          首先创建Lua文件夹,并加上一个.txt后缀更改成文本格式,比如helloworld.lua.txt(注意后面的.txt):
  1. print("Hello world from file")
  2. a=2
  3. b=3
  4. print(a+b)
复制代码
        读取并运行文件中的Lua代码:
  1.         TextAsset ta = Resources.Load<TextAsset>("helloworld.lua"); //   加载 helloworld.lua.txt文本,注意加载.lua文件要加后缀
  2.         LuaEnv env = new LuaEnv();
  3.         env.DoString(ta.text);
  4.         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)。
  1.         LuaEnv env = new LuaEnv();
  2.         //引入并执行Lua代码,是使用loader来加载helloworld.lua.txt,找到就会执行代码,没找到就会报错
  3.         //要确保文件在Resources文件夹下,并保证文件名一致
  4.         env.DoString("require 'helloworld'");
  5.         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读取文件解密后返回即可
示例代码:
  1. using UnityEngine;
  2. using XLua;
  3. using System.IO;
  4. public class CreateLoader : MonoBehaviour {
  5.         void Start () {
  6.         LuaEnv env = new LuaEnv();
  7.         env.AddLoader(MyLoader);//参数是委托的方法名,其实是自定义方法
  8.         //require时会将名字传递给每个loader查找,先执行我们自定义的loader,如果自定义loader返回不为空,则执行改代码,不会再执行内置的loader
  9.         env.DoString("require 'test007'");
  10.         env.Dispose();
  11.         }
  12.     private byte[] MyLoader(ref string filePath)
  13.     {
  14.         string absPath = Application.streamingAssetsPath + "/" + filePath + ".lua.txt";
  15.         return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
  16.     }
  17. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-24 09:36 , Processed in 0.090816 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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