Lua编程1

思考并回答以下问题:

  • 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
12
using 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。

执行后Console窗口

我们来逐行分析一下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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using UnityEngine;
using System.Collections;
using XLua;

namespace Tutorial
{
public class ByFile : MonoBehaviour
{
LuaEnv luaenv = null;

// Use this for initialization
void Start()
{
luaenv = new LuaEnv();
luaenv.DoString("require 'byfile'");
}

// Update is called once per frame
void Update()
{
if (luaenv != null)
{
luaenv.Tick();
}
}

void OnDestroy()
{
luaenv.Dispose();
}
}
}

byfile.lua.txt

1
print('hello world')

Lua中的require有些像C#中的using。实际上是调一个个的加载器loader,来加载一个一个模块/代码文件。与using不同的是,require加载进来后会将代码执行一次

xLua除了Lua原生的loader外,还添加了从Resource加载的loader,所以上面的代码可以加载Resources目录下的byfile.lua.txt文件并执行。

1
2
TextAsset ta = Resources.Load<TextAsset>("byfile.lua");
luaenv.DoString(ta.text);

需要注意的是因为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
5
print(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根据下标可以遍历所有值

0%