思考并回答以下问题:
- LuaEnv luaenv = new LuaEnv();是什么意思?
- luaenv.DoString(“CS.UnityEngine.Debug.Log(‘hello world’)”);是什么意思?
- luaenv.DoString(“require ‘byfile’”);是什么意思?
- luaenv.Dispose是什么意思?
- print(_VERSION);_后加大写字母是什么意思?
- 建议的加载Lua脚本方式是:整个程序就一个DoString(“require ‘main’”),然后在main.lua加载其它脚本(类似lua脚本的命令行执行:lua main.lua)。为什么?
- 在默认情况下,变量总是认为是全局的。直接访问未初始化的全局变量会报错吗?
- 放Resources下的lua文件得加上txt后缀。为什么?
上一节课下载的是release版,由于这节课会用到xLua的Example和Tutorial,在开始之前需要将xLua的整个Github源码下载或者Clone下来。
下载以后,使用Unity打开下载的源码,xLua的示例代码在Assets\XLua\Examples中,xLua的教程在Assets\XLua\Tutorial中。
在Unity里安装xLua并使用,是不需要电脑上有Lua环境的。以下全部在Unity的xLua工程中测试。
Hello World
该例子位于Assets\XLua\Examples\01_Helloworld。1
2
3
4
5
6
7
8
9
10
11
12using UnityEngine;
using XLua;
public class Helloworld : MonoBehaviour
{
void Start ()
{
LuaEnv luaenv = new LuaEnv();
luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");
luaenv.Dispose();
}
}
上面的代码,就是执行了一句Lua代码CS.UnityEngine.Debug.Log(‘hello world’),来打印出hello world。
我们来逐行分析一下Start中的代码:
第1行LuaEnv luaenv = new LuaEnv();,创建了一个Lua环境,类似一个运行时环境,用来解析、执行Lua代码。
第2行luaenv.DoString();是用于执行Lua代码字符串。
第3行luaenv.Dispose();用于释放这个Lua环境。
通过字符串执行代码不够方便,需要加载文件并执行文件中的Lua代码。
从文件加载Lua文件
从文件加载Lua代码文件,用Lua的require函数即可,比如:
完整代码见XLua\Tutorial\LoadLuaScript\ByFile
1 | using UnityEngine; |
byfile.lua.txt
1 | print('hello world') |
Lua中的require有些像C#中的using。实际上是调一个个的加载器loader,来加载一个一个模块/代码文件。与using不同的是,require加载进来后会将代码执行一次。
xLua除了Lua原生的loader外,还添加了从Resource加载的loader,所以上面的代码可以加载Resources目录下的byfile.lua.txt文件并执行。
1 | TextAsset ta = Resources.Load<TextAsset>("byfile.lua"); |
需要注意的是因为Resource只支持有限的后缀,放Resources下的lua文件得加上txt后缀。
建议的加载Lua脚本方式是:整个程序就一个DoString(“require ‘main’”),然后在main.lua加载其它脚本(类似lua脚本的命令行执行:lua main.lua)。
此外很多时候热更新肯定是需要从服务器上下载Lua代码执行,这个后面再说。
下面开始学习lua的语法。后面学习中,如果没有特殊说明,代码会写在上面的byfile.lua.txt文件中,并使用XLua\Tutorial\LoadLuaScript\ByFile场景运行测试。
Lua编程
代码基础
标识符
在Lua中有一个特殊的规则,即以下划线(_)开头,后面紧随多个大写字母(_VERSION),这些变量一般被Lua保留并用于特殊用途,因此我们在声明变量时需要尽量避免这样的声明方式,以免给后期的维护带来不必要的麻烦。
byfile.lua.txt
1 | print(_VERSION) |
结果:
1 | LUA: Lua 5.3 |
Lua是大小写敏感的,因此在Lua中Gold与gold是两个不同的标示符。此外对于一些Lua保留关键字的使用要特别小心,如and。但是And和AND则不是Lua的保留字。
关键字
以下列出了Lua的保留关键字。保留关键字不能作为常量或变量或其他用户自定义标示符:
and break do else elseif end false for function if in local nil not or repeat return then true until while
全局变量
在默认情况下,变量总是认为是全局的。
在Lua中全局变量不需要声明,直接赋值即可。如果直接访问未初始化的全局变量,Lua也不会报错,直接返回nil。如果不想再使用该全局变量,可直接将其置为nil。如:1
2
3
4
5print(b) -- nil
b = 10
print(b) -- 10
b = nil
print(b) -- nil
这样变量b就好像从没被使用过一样。换句话说,当且仅当一个变量不等于nil时,这个变量即存在。
tips
lua的0是true
c#的do while在lua中是repeat until
lua没有+= -= ++ —
lua直接用英文 and or not
#专门原来返回字符串的长度了,以前是表和table。现在分开了。
lua数组的下标从1开始
lua中数组可以存任何东西,包括nil
ipairs遇见空值不遍历了
pairs遍历所有非空值
for根据下标可以遍历所有值