Lua 学习笔记
使用该专栏
本专栏是笔者基于唐老狮的免费公开Lua课程所写的笔记以及拓展了一点其他内容,主要用途是便于笔者自己随时随地复习,同时希望能帮助到有需要的人。
Lua是一种轻量级的脚本语言,由标准C语言编写并以源代码形式开放。它的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua具有以下特性:
轻量级:它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便地嵌入别的程序里。
可扩展:Lua提供了非常易于使用的扩展接口和机制:由宿主语言 (通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
其他特性:支持面向过程 (procedure-oriented)编程和函数式编程 (functional programming);自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象; 语言内置模式匹配;闭包 (closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持; 通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。
在Unity开发中,Lua一般会被使用于热更新和热重载。
Lua
基本语法
;分号是可以省略的,建议不写

注释
单行注释 两个减号是单行注释:
多行注释

全局变量
在默认情况下,变量总是认为是全局的。
全局变量不需要声明,给一个变量赋值后即创建了这个全局变量,访问一个没有初始化的全局变量也不会出错,只不过得到的结果是:nil。
如果你想删除一个全局变量,只需要将变量赋值为nil。

数据类型
Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。
数据类型描述nil这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)有点类似C#中的null。boolean包含两个值:false和true。number表示双精度类型的实浮点数string字符串由一对双引号或单引号来表示function由 C 或 Lua 编写的函数userdata表示任意存储在变量中的C数据结构thread表示执行的独立线路,用于执行协同程序tableLua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。
简单变量类型
nil, number, string, boolean
复杂数据类型
函数 function
表 table
数据结构 userdata:
userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。
协同程序 thread:
在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。
线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。
变量声明
lua中所有的变量声明 都不需要申明变量类型,它会自动判断变量类型,类似C#中的 var
lua中的一个变量 可以随便赋值,自动识别类型
我们可以使用 type 函数测试给定变量或者值的类型:
nil 类型表示一种没有任何有效值,它只有一个值 -- nil,例如打印一个没有赋值的变量,便会输出一个 nil 值:
对于全局变量和 table,nil 还有一个"删除"作用,给全局变量或者 table 表里的变量赋一个 nil 值,等同于把它们删掉,执行下面代码就知:
nil 作比较时应该加上双引号 ":
type(X)==nil 结果为 false 的原因是 type(X) 实质是返回的 "nil" 字符串,是一个 string 类型:

字符串
字符串的声明,使用单引号或者双引号包裹,lua里没有char
获取字符串的长度
字符串多行打印
字符串拼接
别的类型转成字符串
字符串提供的公共方法,大部分方法不会对原字符串造成影响

运算符
算数运算符
+-*/% 在lua中没有自增自减 ++ --;没有复合运算符 += -= /= *= %=
条件运算符
逻辑运算符
位运算符
-- & | 不支持位运算符 需要我们自己实现
三目运算符
-- ? : lua中 也不支持三目运算

条件分支语句
循环语句

函数
无参数无返回值
有参数
有返回值
函数的类型
函数的重载
变长参数
函数嵌套
闭包

复杂数据类型——表
所有的复杂类型都是table(表)
数组的遍历
二维数组
二维数组的遍历
自定义索引

迭代器遍历
迭代器遍历,主要是用来遍历表的
#得到的长度并不准确,所以一般不要用#来遍历表

复杂数据类型——表2
字典
字典的本质还是表
字典的声明
字典是由键值对构成的
字典的遍历

类和结构体
Lua中是默认没有面向对象的,需要我们自己来实现
表的公共操作

多Lua脚本执行
全局变量与本地变量
多脚本执行
脚本卸载
大G表

特殊用法
多变量赋值
多返回值
and or

协同程序
协程的创建
协程的运行
协程的挂起
协程的状态

元表
元表概念
任何表变量都可以作为另一个表变量的元表
任何表变量都可以有自己的元表(爸爸)
当我们子表中进行一些特定操作时 会执行元表中的内容
设置元表
特定操作
特定操作 - __tostring
特定操作 - __call
特定操作 - 运算符重载
特定操作 - __ index和 __ newIndex

面向对象
封装
继承
多态

Lua自带库
时间
数学运算
路径
Lua垃圾回收

如何在游戏中执行用户输入的代码
在游戏中执行用户输入的代码需要谨慎,因为这可能会带来安全风险。如果您确实想要实现这个功能,您可以考虑在游戏中嵌入一个脚本引擎,例如Lua或Python。这样,您可以在运行时执行用户输入的脚本代码。
首先,您需要在游戏中创建一个文本输入框,让用户可以输入代码。然后,您可以使用脚本引擎提供的API来执行用户输入的代码。例如,在Unity中使用xLua插件,您可以使用DoString
方法来执行用户输入的Lua代码。
什么是XLua
xLua是一个在Unity中使用Lua语言的插件。它提供了一种简单的方法来在Unity项目中嵌入Lua脚本,并在运行时执行这些脚本。
xLua具有许多优点,包括简单易用、性能高效和跨平台支持。它还支持热更新,可以让您在不重新编译和发布游戏的情况下更新游戏逻辑。
使用xLua,您可以将游戏逻辑和界面逻辑分离,使用Lua脚本来实现游戏逻辑。这样,您可以更快地迭代游戏逻辑,并且可以在运行时动态更新游戏逻辑。
xLua提供了丰富的文档和示例,可以帮助您快速入门。如果您想要在Unity项目中使用Lua语言,那么xLua是一个不错的选择。
要使用xLua编写游戏逻辑,您需要先在Unity项目中安装xLua插件。安装完成后,您可以在Unity项目中创建Lua脚本文件,并使用Lua语言编写游戏逻辑。
xLua提供了一组API,可以让您在Lua脚本中访问Unity的功能。例如,您可以使用
命名空间来访问Unity的类和方法。您还可以使用
方法来热更新C#代码。
下面是一个简单的示例,演示如何使用xLua编写游戏逻辑:
在这个示例中,我们定义了一个move
函数,用于移动游戏物体。然后,在update
函数中调用move
函数,使物体每帧都移动一定距离。
如何安装XLua
要在Unity中安装和使用xLua,您可以按照以下步骤操作:
访问xLua的GitHub页面(https://github.com/Tencent/xLua),并下载最新版本的xLua插件。
将下载的xLua插件解压缩到您的Unity项目的Assets文件夹中。
在Unity编辑器中,打开您的项目,并确保xLua插件已经导入到项目中。
在Unity项目中创建一个C#脚本,用于初始化xLua环境。例如:
在这个示例中,我们创建了一个XLuaManager
类,用于管理xLua环境。在Start
方法中,我们创建了一个LuaEnv
实例,并执行了一个名为main
的Lua脚本。在Update
方法中,我们调用了luaEnv.Tick
方法来更新xLua环境。最后,在OnDestroy
方法中,我们释放了xLua环境。
在Unity项目中创建一个名为
main.lua
的文件,并使用Lua语言编写游戏逻辑。例如:
在这个示例中,我们创建了一个简单的Lua脚本,用于输出一条消息。
运行您的Unity项目,并检查控制台输出。如果一切正常,您应该能看到来自Lua脚本的输出。
如何在Lua中访问Unity的功能
在使用xLua的Unity项目中,您可以在Lua脚本中访问Unity的类和方法。xLua提供了一个全局的CS
表,用于访问C#的命名空间和类型。
例如,要在Lua脚本中访问Unity的Vector3
类,您可以使用以下代码:
在这个示例中,我们使用CS.UnityEngine.Vector3
来访问Unity的Vector3
类,并将其赋值给一个局部变量。然后,我们就可以在Lua脚本中使用这个局部变量来创建和操作Vector3
对象。
除了访问Unity的类和方法外,您还可以在Lua脚本中访问Unity的组件和游戏对象。例如,要在Lua脚本中访问当前游戏对象的Transform组件,您可以使用以下代码:
在这个示例中,我们使用self.transform
来访问当前游戏对象的Transform组件,并将其赋值给一个局部变量。然后,我们就可以在Lua脚本中使用这个局部变量来操作Transform组件。
如何在Lua中处理输入事件
在使用xLua的Unity项目中,您可以在Lua脚本中处理输入事件。要做到这一点,您需要在C#脚本中监听输入事件,并将它们传递给Lua脚本。
例如,要在Lua脚本中处理鼠标点击事件,您可以在C#脚本中监听鼠标点击事件,并调用Lua脚本中定义的函数来处理这些事件。下面是一个简单的示例:
在这个示例中,我们定义了一个InputManager
类,用于管理输入事件。在Update
方法中,我们监听鼠标点击事件,并调用Lua脚本中定义的onMouseDown
函数来处理这些事件。
在这个示例中,我们获取了InputManager
类的实例,并为其onMouseDown
属性赋值了一个函数。当鼠标点击事件发生时,这个函数将被调用,并输出一条消息。
这就是在Lua脚本中处理输入事件的基本方法。您可以根据需要扩展这个方法,以支持更多类型的输入事件。