Unity Lua教程

一、环境搭建

1、首先安装LuaForWindows,官网地址:https://github.com/rjpcomputing/luaforwindows/releases
2、安装Sublime Text,官网地址:https://www.sublimetext.com/download
3、如果大家下载不了的话,可以通过我提供的百度网盘进行下载:
链接:https://pan.baidu.com/s/1ojhEqgUoEtozdS3itTY1_Q
提取码:nw68

二、基本语法(lua语句 可以省略分号)

1、打印函数

print("hello world")

2、注释

--单行注释

--[[
第一种多行注释
]]

--[[
第二种多行注释
]]--

--[[
第三种多行注释
--]]

3、关键字
关键字
4、数据类型
数据类型
5、查看变量的类型

print(type(a))
--type的返回值为string类型

--lua中使用没有声明过的变量,不会报错,默认值是nil

6、字符串

s="521一生一世"
print(#s)  --获取字符串的长度,一个汉字占3个长度,英文字符占一个长度

--字符串多行打印
print("123\n123")
s=[[
521
1314
]]
print(s)

--字符串拼接
print("123".."456")  --通过两个..
print(string.format("小明今年%d岁了",18)
--%d:与数字拼接
--%a:与任何字符拼接
--%s:与字符配对

--别的类型转字符串
a=18
print(tostring(a))

--字符串提供的公共方法
str="aBcDe"
print(string.upper(str))  --小写转大写的方法
print(string.lower(str))  --大写转小写的方法
print(string.reverse(str))  --翻转字符串
print(string.find(str,"cDe"))  --字符串索引查找,Lua中索引下标从1开始
print(string.sub(str,3))  --截取字符串
print(string.rep(str,2))  --字符串重复
print(string.gsub(str,"cD","**"))  --字符串修改

a=string.byte("Lua",1)  --给指定位置的字符转成ASCII码
print(a)
print(striing.char(a))  --ASCII码转字符

7、运算符

--算术运算符
	-- + - * / % ^
	-- 没有自增自减 ++ --
	-- 没有复合运算符 += -= /= *= %=
	-- 字符串可以进行算术运算符操作,会自动转成number
	print("123"+1)  --结果为:124
	print("幂运算:"..2^5)

--条件运算符
	-- > < >= <= == ~=(不等于)

--逻辑运算符
	--and--or--not-- Lua中支持“短路”,只要第一个条件成立,后面的语句就不执行

--位运算符
	--Lua中不支持位运算

--三目运算符
	--Lua中不支持三目运算符

8、条件分支语句

--单分支
if 条件 then
	...
end

--双分支
if 条件 then
	...
else
	...
end

--多分支
if 条件 then
	...
elseif 条件 then  --elseif是连着写的,要不然会报错
	...
else
	...
end

--Lua中没有Switch语法,需要自己实现

9、循环语句

--while语句
while 条件 do
	...
end

--do while语句
repeat
	...
until 条件 --结束条件,满足条件退出

--for语句
for i=1,5 do  --1开始到5结束,i默认递增+1,如果要自定义增量,要这样写:i=1,5,2
	...
end

10、函数

--无参数无返回值,两种方法
function F1()  --一个在function后面取名字
	...
end

F2 = function()  --一个不取名字,用一个变量来存储
	...
end

--有参数,如果传入的参数和函数参数个数不匹配,不会报错,只会补空nil或者丢弃
function F3(a)
	...
end

--有一个返回值
function F4(a)
	return a
end

--有多个返回值,需要申明多个变量来接取,接少接多不影响,少了丢弃,多了为nil
function F5(a)
	return a,b,c
end

--函数类型就是function

--不支持函数的重载

--变长参数
function F6(...)
	arg = {...}
	for i=1,#arg do
		print(arg[i])
	end
end
F6(1,"123",true,456)

--函数嵌套,函数里面申明函数
function F7()
	return function()
		print(123)
	end
end
F8 = F7()
F8()

--闭包,改变传入参数的生命周期
function F9(x)
	return function(y)
		return x + y
	end
end
F10 = F9(10)
print(F10(5))  --15

11、复杂数据类型table

--所有的复杂类型都是table

--数组的声明和使用
a = {1,2,"123",true,nil,"456"}
print(a[1])  --Lua中索引从1开始
print(#a)  --获取数组的长度,#是通用的获取长度的关键字,在打印长度的时候,第一个空后面的内容会被忽略

--数组的遍历
for i=1,#a do
	print(a[i])
end

--二维数组
b = {{1,2,3},{4,5,6}}
print(b[1][2])

--二维数组的遍历
for i=1,#b do
	c=b[i]
	for j=1,#c do
		print(c[j])
	end
end

--自定义索引
aa={[0]=1,2,3,[-1]=4}  --#aa打印结果为2,忽略小于等于0的索引
bb={[1]=1,[2]=2,[4]=4,[6]=6}  --有坑,#bb打印的结果为6,索引之间可以跳一个,缺的补nil
cc={[1]=1,[2]=2,[5]=5,[6]=6}  --#cc打印结果为2

--迭代器遍历,主要是用来遍历表的,一般不要用#来遍历表
a={[0]=1,2,[-1]=3,4,5,[5]=6}

--ipairs遍历,还是从1开始往后遍历的,小于等于0的值得不到
--只能找到连续索引的键,如果中间断序了,它也无法遍历出后面的内容
for i,k in ipairs(a) do
	print(i.."_"..k)  --1_2 2_4 3_5
end

--pairs它能够把所有的键都找到,通过键可以得到值
for i,v in pairs(a) do
	print(i.."_"..v)  --1_2 2_4 3_5 0_1 -1_3 5_6
end

--只遍历键
for i in pairs(a) do
	print(i)
end

12、字典

--字典的声明,字典是由键值对构成
a={["name"]="张三",["age"]=18,["sex"]="男"}
print(a["name"])  --访问
print(a.name)  --虽然可以通过.成员变量的形式得到值,但是不能是数字
a["name"]="李四"  --修改
a["score"]=100  --新增
a["score"]=nil  --删除

--字典的遍历
for k,v in pairs(a) do
	print(k,v)
end

13、类和结构体

--Lua中默认是没有面向对象的,需要我们自己来实现

--类的声明,成员变量,成员函数
Student = {
	age=18,
	sex=true,
	Up=function()
		--这样写 这个age和表中的age没有任何关系 它是一个全局变量
		--print(age)

		--想要在表的内部函数中 调用表本身的属性或者方法
		--一定要指定是谁的 所以要使用 表名.属性 或者 表名.方法
		print(Studnet.age)

		print("Grow up!");
	end
}
print(Student.age)  --调用
Student.Up()

--申明表过后,在表外去申明表有的变量和方法
Student.name="张三"

Student.Learn=function(t)
	--第二种 能够在函数内部调用自己属性或者方法的 方法
	--把自己作为一个参数传进来 在内部 访问
	print(t.sex)
	
	print("好好学习,天天向上")
end
Student.Learn(Student)
Student:Learn()  --冒号调用方法 会默认把调用者 作为第一个参数传入方法中

function Student:Speak()  --冒号声明函数
	--Lua中 有一个关键字 self 表示默认传入的第一个参数
	print(self.name.."说话")
end	

14、表的公共操作

t1={{age=1,name="123"},{age=2,name="345"}}
t2={name="张三",sex=true}

--将t2插入t1
table.insert(t1,t2)

--移除最后一个索引的内容
table.remove(t1)

--移除指定位置的内容
table.remove(t1,1)

t3={4,8,1,3,6,9}
table.sort(t3)  --升序排序

table.sort(t3,function(a,b)
	if a>b then
		return true
	end
end)  --降序排序

--拼接
tb={"123","456","789"}
table.concat(tb,",")

15、多脚本执行

--全局变量和本地变量
--本地变量就是在变量前加local关键字
--不加local关键字的都是全局变量

--多脚本执行语法:require("脚本名")require('脚本名')
--如果是require加载执行的脚本 加载一次过后不会再被执行

--脚本卸载
--package.loaded["脚本名"]  --返回值是boolean 意思是 该脚本是否被执行
package.loaded["脚本名"]=nil  --卸载已经执行过的脚本

--大G表:是一个总表 它将我们申明的所有全局的变量都存储在其中
--写法:_G
_G["a"] = 1  --大G表中声明
print(a)

--如果想在另外一个脚本中访问该脚本中的本地变量,可以通过return返回,在另一个脚本中用变量接收即可

16、特殊用法

--多变量赋值,如果后面的值不够,会自动补空;如果后面的值多了,会自动省略
a,b,c=1,2,3

--多返回值
function Test()
	return 10,20,30,40
end
a,b,c=Test()  --多返回值时 你用几个变量接 就有几个值 如果少了 就少接几个 如果多了 就自动补空

--逻辑与 逻辑或
--and or 他们不仅可以连接boolean 任何东西都可以用来连接
--在Lua中 只有nil和false才认为是假
--“短路” 对于and来说 有假则假 对于or来说 有真则真
--所以他们只需要判断 第一个 是否满足 就会停止计算了
print(1 and 2)  --2
print(0 and 1)  --1
print(nil and 1)  --nil
print(false and 2)  --2
print(true or 1)  --true
print(nil or 2)  --2

--Lua不支持三目运算符,模拟三目运算符
x=3
y=2
res=(x>y) and x or y

--(x>y) and x -> x  --x>y为真
--x or y -> x

--(x>y) and x -> (x>y)  --x>y为假
--(x>y) or y -> y

17、协同程序

--协程的创建 协程的本质是一个线程对象
--第一种方法:coroutine.create() 常用方式 返回的是一个thread
fun = function()
	print(123)
end
co = coroutine.create(fun)

--第二种方法:coroutine.wrap() 返回的是function
co2 = coroutine.wrap(fun)

--协程的运行
coroutine.resume(co)  --用第一种方法创建的协程的运行方法
co2()  --第二种

--协程的挂起
fun2 = function()
	local i=1
	while true do
		print(i)
		i = i + 1
		coroutine.yield(i)  --协程的挂起函数 可以有返回值
	end
end
co3 = coroutine.create(fun2)  
coroutinee.resume(co3)  --1
coroutinee.resume(co3)  --2
isOk,tempI = coroutinee.resume(co3)  --默认第一个返回值是协程是否启动成功,第二个是yield里面的返回值

co4 = coroutine.wrap(fun2)
co4()  --1
co4()  --2
print(co4)  --这种方式的协程调用 也可以有返回值 只是没有默认第一个返回值了

--协程的状态:coroutine.status(协程对象)
--有三种状态:dead 结束  suspended 暂停  running 进行中

--得到当前正在运行的协程的线程号
coroutine.running()

18、元表

--元表的概念
--任何表变量都可以作为另一个表变量的元表
--任何表变量都可以有自己的元表(爸爸)
--当我们子表中进行一些特定操作时 会执行元表中的内容

--设置元表
meta={}
myTable={}
--设置元表函数 第一个参数 子表 第二个参数 元表(爸爸)
setmetatable(myTable,meta)

--特定操作 __tostring 当子表要被当做字符串使用时 会默认调用这个元素中的tostring方法
meta2={
	__tostring = function(t)
		return t.name
	end
}
myTable2={
	name = "张三"
}
setmetatable(myTable2,meta2)
print(myTable2)

--特定操作 __call
meta3={
	__tostring = function(t)
		return t.name
	end,
	--__当子表被当做一个函数来使用时 会默认调这个__call中的内容
	__call = function()  --当希望传参数时 一定要记住 默认第一个参数 是调用者自己
		print("李四")
	end
}
myTable3={
	name = "张三"
}
setmetatable(myTable3,meta3)
print(myTable3)
myTable3()

--运算符重载
meta4={
	--相当于运算符重载 当子表使用+运算符时 会调用该方法
	__add = function(t1,t2)
		return t1.age + t2.age
	end
	-- 运算符-:__sub
	-- 运算符*:__mul
	-- 运算符/:__div
	-- 运算符%:__mod
	-- 运算符^:__pow
	
	-- 如果要用条件运算符来比较两个对象,这两个对象的元表一定要一致,才能准确调用方法
	-- 运算符==:__eq
	-- 运算符<:__lt
	-- 运算符<=:__le
	
	-- 运算符..:__concat
}
myTable4={age = 1}
setmetatable(myTable4,meta4)
myTable5={age = 2}
print(myTable4+myTable5) --3

--特定操作 __index 和 __newIndex
meta6={
	__index = {age = 1}
}
--meta6.__index = {age = 2}

--meta6={
--	age=1
--}
--meta6.__index = meta6

myTable6={}
setmetatable(myTable6,meta6)
--__index 当子表中找不到某一个属性时 会在元表中 __index指定的表去找索引 建议写在外面
print(myTable6.age)

print(getmetatable(myTable6))  --得到元表的方法

print(rawget(myTable6,"age"))  --rawget 当我们使用它时 会去找自己身上有没有这个变量

--newindex 当赋值时 如果赋值一个不存在的索引 那么会把这个值赋值到newIndex所指的表中 不会修改自己
meta7={}
meta7.__newindex={}
myTable7={}
setmetatable(myTable7,meta7)
myTable7.age=1
print(myTable7.age)  --nil
print(myTable.__newindex.age)  --1

rawset(myTable7,"age",2)  --该方法 会忽略newindex的设置 只会改自己的变量
print(myTable7.age)  --2

19、面向对象

-- 面向对象 类 其实都是基于table来实现的
-- 面向对象之封装
Object = {}
Object.id = 1
function Object:Test()
	print(self.id)
end
--冒号 是会自动将调用这个函数的对象 作为第一个参数传入的写法
function Object:new()
	--self 代表的是 我们默认传入的第一个参数
	local obj = {}
	--元表知识 __index 当找自己的变量 找不到时 就会去找元表当中 __index指向的内容
	self.__index = self

	obj.base = self  --子类 定义个base属性 代表父类
	
	setmetatable(obj,self)
	return obj
end

local myObj = Object:new()
print(myObj.id)  --1
myObj:Test()  --1
--对空表中 声明一个新的属性 叫做id
--myObj.id=2
--print(Object.id) --1

myObj.id = 2
myObj:Test()  --2

--面向对象之继承
function Object:subClass(className)
	-- _G知识点 是总表 所有声明的全局变量 都以键值对的形式存在其中
	_G[className]={}
	local obj = _G[className]
	self.__index = self
	setmetatable(obj,self)
end

Object:subClass("Person")
print(Person.id)  --1
local p = Person:new()
print(p.id)  --1

--面向对象之多态
Object:subClass("GameObject")
GameObject.posX = 0
GameObject.posY = 0
function GameObject:Move()
	self.posX = self.posX + 1
	self.posY = self.posY + 1
	print(self.posX,self.posY)
end

GameObject:subClass("Player")
function Player:Move()
	self.base:Move()

	--我们如果要执行父类逻辑 就不能直接使用冒号调用 要通过.调用 然后自己传入第一个参数
	--self.base.Move(self)  --填坑
end

local p1 = Player:new()
p1:Move()  --1 1

--目前这种写法 有坑 不同对象使用的成员变量 居然是相同的成员变量 不是自己的
local p2 = Player:new()
p2:Move()  --2 2

20、面向对象总结

Object = {}

function Object:new()  -- 封装
	local obj = {}
	--给空对象设置元素 以及 __index
	self.__index = self
	setmetatable(obj,self)
	return obj
end

function Object:subClass(className)  -- 继承
	--根据大G表的特性 根据名字生成一张表 就是一个类
	_G[className] = {}
	local obj = _G[className]

	obj.base = self  --设置自己的“父类” 多态
	
	--给子类设置元表 以及 __index
	self.__index = self
	setmetatable(obj,self)
end

--多态
Object:subClass("GameObject")  --声明一个新的类
GameObject.posX = 0  --成员变量
GameObject.posY = 0
function GameObject:Move()  --成员方法
	self.posX = self.posX + 1
	self.posY = self.posY + 1
	print(self.posX,self.posY)
end

GameObject:subClass("Player")  --声明一个新的类 Player 继承 GameObject
function Player:Move()  --多态 重写了GameObject的Move方法
	--self.base.Move(self)  --base调用父类方法 用.自己传第一个参数
end

--实例化对象使用
local obj1 = GameObject:new()
print(obj1.posX)  --0
obj1:Move()
print(obj1.posX)  --1

local obj2 = GameObject:new()
print(obj2.posX)  --0
obj2:Move()
print(obj2.posX)  --1


local p1 = Player:new()
print(p1.posX)  --0
p1:Move()
print(p1.posX)  --1

local p2 = Player:new()
print(p2.posX)  --0
p2:Move()
print(p2.posX)  --1

21、自带库

--时间
print(os.time())  --系统时间

local nowTime = os.date("*t")  --详细时间
for k,v in pairs(nowTime) do
	print(k,v)
end
print(nowTime.year)

--数学运算
print(math.abs(-1))  --绝对值
print(math.deg(math.pi))  --弧度转角度
print(math.cos(math.pi))  --三角函数
print(math.floor(2.6))  -- 2 向上取整
print(math.ceil(5.2))  -- 6 向下取整
print(math.max(1,2))  -- 2 最大值
print(math.min(4,5))  -- 4 最小值
print(math.modf(1.2))  --小数分离 分成整数部分和小数部分
print(math.pow(2,5))  --幂运算
print(math.sqrt(4))  --开方
--随机数
math.randomseed(os.time)  --随机数种子
print(math.random(100))

--路径
print(package.path)  --lua脚本加载路径

22、Lua垃圾回收

--垃圾回收关键字:collectgarbage

--获取当前Lua占用内存数 K字节 用返回值*1024 就可以得到具体的内存占用字节数
print(collectgarbage("count"))

--进行垃圾回收
collectgarbage("collect")

--Lua中 有自动定时进行GC的方法
--Unity中热更新开发 尽量不要去用自动垃圾回收
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
lua中文教程,原名:programming in lua 目录 版权声明..............i 译序..i 目录iii 第一篇语言.......1 第0章序言.......1 0.1 序言..........1 0.2 Lua的使用者................2 0.3 Lua的相关资源............3 0.4 本书的体例.................3 0.5 关于本书...3 0.6 感谢..........4 第1章起点.......5 1.1 Chunks.......5 1.2 全局变量...7 1.3 词法约定...7 1.4 命令行方式.................7 第2章类型和值9 2.1 Nil..............9 2.2 Booleans....9 2.3 Numbers...10 2.4 Strings......10 2.5 Functions.12 2.6 Userdata and Threads.12 第3章表达式..13 3.1 算术运算符...............13 3.2 关系运算符...............13 3.3 逻辑运算符...............13 3.4 连接运算符...............14 3.5 优先级.....15 3.6表的构造..15 第4章基本语法................18 4.1 赋值语句.18 4.2 局部变量与代码块(block)......19 4.3 控制结构语句...........20 Programming in Lua iv Copyright ® 2005, Translation Team, www.luachina.net 4.4 break和return语句......23 第5章函数......24 5.1 返回多个结果值.......25 5.2可变参数..27 5.3 命名参数.28 第6章再论函数................30 6.1 闭包........32 6.2 非全局函数...............34 6.3 正确的尾调用(Proper Tail Calls)...36 第7章迭代器与泛型for....40 7.1 迭代器与闭包...........40 7.2 范性for的语义...........42 7.3 无状态的迭代器.......43 7.4 多状态的迭代器.......44 7.5 真正的迭代器...........45 第8章编译·运行·调试47 8.1 require函数.................49 8.2 C Packages.................50 8.3 错误........51 8.4 异常和错误处理.......52 8.5 错误信息和回跟踪(Tracebacks)....53 第9章协同程序................56 9.1 协同的基础...............56 9.2 管道和过滤器...........58 9.3 用作迭代器的协同...61 9.4 非抢占式多线程.......63 第10章完整示例..............68 10.1 Lua作为数据描述语言使用........68 10.2 马尔可夫链算法.....71 第二篇 tables与objects........75 第11章数据结构..............76 11.1 数组......76 11.2 阵和多维数组.........77 11.3 链表......78 11.4 队列和双端队列.....78 11.5 集合和包.................80 11.6 字符串缓冲.............80 第12章数据文件与持久化..................84 12.1 序列化...86 Programming in Lua v Copyright ® 2005, Translation Team, www.luachina.net 第13章 Metatables and Metamethods...92 13.1 算术运算的Metamethods............92 13.2 关系运算的Metamethods............95 13.3 库定义的Metamethods................96 13.4 表相关的Metamethods................97 第14章环境..103 14.1 使用动态名字访问全局变量...103 14.2声明全局变量........104 14.3 非全局的环境.......106 第15章 Packages.............109 15.1 基本方法...............109 15.2 私有成员(Privacy)................111 15.3 包与文件................112 15.4 使用全局表............113 15.5 其他一些技巧(Other Facilities)...115 第16章面向对象程序设计.................118 16.1 类.........119 16.2 继承.....121 16.3 多重继承...............122 16.4 私有性(privacy)...................125 16.5 Single-Method的对象实现方法127 第17章 Weak表...............128 17.1 记忆函数...............130 17.2 关联对象属性.......131 17.3 重述带有默认值的表...............132 第三篇标准库134 第18章数学库................135 第19章 Table库...............136 19.1数组大小................136 19.2 插入/删除..............137 19.3 排序.....137 第20章 String库..............140 20.1 模式匹配函数.......141 20.2 模式.....143 20.3 捕获(Captures).146 20.4 转换的技巧(Tricks of the Trade)151 第21章 IO库..157 21.1 简单I/O模式..........157 21.2 完全I/O 模式........160 Programming in Lua vi Copyright ® 2005, Translation Team, www.luachina.net 第22章操作系统库........165 22.1 Date和Time............165 22.2 其它的系统调用...167 第23章 Debug库..............169 23.1 自省(Introspective)..............169 23.2 Hooks...173 23.3 Profiles.174 第四篇 C API..177 第24章 C API纵览..........178 24.1 第一个示例程序...179 24.2 堆栈.....181 24.3 C API的错误处理..186 第25章扩展你的程序....188 25.1 表操作.189 25.2 调用Lua函数.........193 25.3 通用的函数调用...195 第26章调用C函数..........198 26.1 C 函数..198 26.2 C 函数库................200 第27章撰写C函数的技巧..................203 27.1 数组操作...............203 27.2 字符串处理...........204 27.3 在C函数中保存状态.................207 第28章 User-Defined Types in C........212 28.1 Userdata.................212 28.2 Metatables..............215 28.3 访问面向对象的数据...............217 28.4 访问数组...............219 28.5 Light Userdata........220 第29章资源管理............222 29.1 目录迭代器...........222 29.2 XML解析...............225
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值