boxmoe_header_banner_img

菜就多练喵

文章导读

[Unity]热更新04——Lua语法


avatar
Ib_Mccf 2026年1月20日 26

注释

print("Hello World")

--这是注释

--[[
  这是多行注释
]]

--[[
  这还是多行注释
]]--

--[[
  这当然也是
--]]

变量类型

--nil为空类型
a = nil
print(type(a))
--整数或浮点数为number类型
a = 1
print(type(a))
a=1.1
print(type(a))
--单双引号包裹为string类型
a = "9992S"
print(type(a))
a = '9992313sss'
print(type(a))
--true或false为boolean类型
a= true
print(type(a))
a = false
print(type(a))

字符串操作

str = "字符串";
str2 = "114514";
str3 = "abs"
--字符串前加#获取字符串长度,中文字符长度为3
print(#str)

print(string.reverse(str2));
print(string.byte(str3,1));
print(string.char(string.byte(str3,1)));
print(string.upper(str3))

条件分支

--条件分支语句
a = 0;
if a > 1 then
    print("a > 1");
elseif a<0 then
    print("a<0");
else 
    print("0<=a<=1");
end

--lua中没有switch

循环

--循环语句

--while循环
num = 0;
while num < 5 do
    num = num+1;
    print(num);
end

--repeat循环,满足until后跳出
num = 0;
repeat
    print(num);
    num = num +1;
until num > 5

--for循环,从1到5,默认递增+1
for i = 1,5 do
    print(i);
end 

--第三个参数为递增2.1
for i = 1, 9,2.1 do
print(i);
end

函数

--*******申明一个函数,不能在申明前调用*******
function func(a)
    print(a)	
end
--调用,没有传入参数类型限制
func(114514)
func("114514")
--传入多余参数,会自动丢弃
func(1,2,3,45)

--*******有返回值的函数*******
function F4(a)
    --可以返回多个值
    return a,1
end
--可以使用参数接收返回值,接收多个返回值
re1,re2 = F4(12312);
print(type(F4));
print(re1)
print(re2)

--*******使用参数接收函数*******
F1 = function()
    print("123")
end 

--*******lua中不支持函数重载,会默认调用最后一个申明的函数*******
F1 = function()
    print("233")
end

F1() --=> 233

--*******变长参数*******
F1 = function(...)
    --先将参数用一个表table存起来
    arg = {...}
    for i=1,#arg do
        print(arg[i])
    end
end
--传入变长参数
F1(1,1,1.243,12,true,"asdasd",31,23)

--*******函数嵌套,返回一格函数*******
--闭包
F11 = function(x)
    --改变传入参数的生命周期
    return function(y)
        return x+y
    end
    end

f10 = F11(10)
print(f10(2))

复杂数据类型——表Table

--****表Table,元素可以是不同类型***
a = {1,2,3,4,5,6,True,"123123",nil}
--lua中索引从1开始
print(a[0]) -- => nil
--输出第一个元素
print(a[1]) -- => 1
-- #获取Table的长度,但若元素有nil,会影响#获取的长度
print(#a) -- => 6 ???

--*******遍历Table********
--由于#的不确定性,for循环遍历Table是不可靠的
for i=1,#a,1 do
	 print(a[i])
end 
-- => 1,2,3,4,5,6

--*******二维数组********
--Table套Table
a = { {1,2,3},{4,5,6}}
print(a[2][1]) -- => 4
--for循环遍历二维数组
for i=1,#a do
	for j=1,#a[i] do
		print(a[i][j])
	end
end

--******自定义索引*******
--自定义索引也会影响#获取长度!
aa = {[0] = 1,2,3,[-1] = 4,5}
print(aa[0]) -- => 1
print(aa[-1]) -- => 4
print(#aa) -- => 3

迭代器遍历——表遍历

--迭代器遍历
a = { 1,2,[-1] = 3,4,[7] = 5,6};

--ipairs迭代器遍历,从索引1开始往后遍历,小于等于0的索引值得不到,中断的索引也无法得到
for i,k in ipairs(a) do
	print("ipairs遍历键值"..i.."_"..k)  --=> 1_1 2_2 3_4 4_6
end

--pairs迭代器遍历
--可以把所有的键值找到
for i,k in pairs(a) do
	print("pairs遍历键值"..i.."_"..k)  --=> 1_1 2_2 3_4 4_6 -1_3 7_5
end

for i in pairs(a) do
	print("pairs遍历键"..i)  --=> 1_1 2_2 3_4 4_6 -1_3 7_5
end

ipairs 和 pairs 迭代器遍历的区别:

ipairs 无法获取索引小于等于0的键值,且索引中断后无法获取后续键值,无法完整遍历。中途遇到值为nil的元素也会中断遍历。类似#获取表长尽心for循环遍历。

pairs 可以获取所有的键值,可以用于遍历索引不规则的表

使用表来实现字典(自定义索引实现键值对)

--用表实现 字典
--通过自定义索引实现键值对
a = {["name"] = "神秘人", ["age"] = 15, ["1"] = 5}

print(a["name"])
print(a["age"])
--a.成员变量可以获取值,但成员变量名不能是数字
print(a.name)

--修改与增加元素
a.name = "新生"
print(a.name)
a["age"] = 25
print(a["age"])

a["sex"] = "男"
print(a.sex)
--删除元素
a.sex = nil

--遍历字典
for k,v in pairs(a) do
	print("获取键值对"..k.."_"..v)
end

.和:都可以调用函数,区别是:会将调用者作为第一个参数传入。

若用:来申明一个函数,默认会将调用者作为第一个参数,并可以使用self变量来访问

--Lua中默认是没有面向对象的,需要自己实现
--通过Table模拟类的成员和成员函数
Student = {
	age = 22,

	sex = true,

	Up = function()
		--这个age是全局变量,不是Student中的age
		print(age) -- => nil
		--应该是
		print(Student.age)
		print("成长")
	end,

	Learn = function(stu)
		--将调用者作为参数传入
		print(stu.name.."正在学习")
	end

}

--类的成员可以在外部修改和增删
Student.name ="神秘内裤反穿男"
Student.Speak = function(content)
	print(Student.name.."说:"..content)
end

Student.Speak("Hello")
print(Student.age)
Student.Up()
--lua中调用函数有两种方法 . 需要传入参数,: 则会将调用者作为第一个参数传入
Student.Learn(Student)
Student:Learn()

--使用:来申明一个函数,self变量为传入的第一个参数
function Student:Learn2()
	print(self.name.."正在学习2")
end
Student:Learn2() --=>神秘内裤反穿男正在学习2
b = {name = "Test"}
--可以将别的表作为参数传入,self对应第一个传入的参数
Student.Learn2(b) --=>Test正在学习2

Table的公共方法

--表的公共操作
t1 = {{age =1 ,name = "123"},
	{age = 114514,name = "2344"}}

t2 = {name ="Fuck",sex = false}

--*****插入*****
print(#t1) --=>2
--将t2中的元素插入到t1
table.insert(t1,t2)
print(#t1) --=>3

--*****删除****
--传入Table,移除最后一个索引的内容
table.remove(t1)
--第二个参数可以填需要删除内容的索引
table.remove(t1,1)

--*****升序排序*****
t2 = {2,25,2,52,5,125}
table.sort(t2)
for k,v in pairs(t2) do
	print(k.."_"..v)
end

--*****降序排序*****
--第二个参数为自定义排序方法
table.sort( t2, 
	function(a,b)
       if a > b then return true end
	end)
for k,v in pairs(t2) do
	print(k.."_"..v)
end

--*****拼接*****
tb = {"1231","12se","123123","Fafaf"}
--拼接表内元素,用,分隔
str = table.concat( tb, ", ")
print(str)

全局变量和局部变量(local)

for i=1,2 do
	--直接声明的变量是全局变量
	c = "114514";
end

for i=1,2 do
	--加local即为局部变量
	local d = "114514"
end

print(c) -- => 114514
print(d) -- => nil

其他lua脚本的加载与卸载

脚本可以return一个局部变量让其他脚本require加载时接收

--*****多脚本执行*****
--关键字 require("脚本名")
--执行对应的脚本
require("Test114514")
print(testA) --=> 打印 "Test114514" 中的全局变量
print(testLocalA) --=> nil 无法获取其他脚本 "Test114514" 中的局部变量

--*****卸载脚本*****]
require("Test114514") --=> 加载过一次后再次加载不会执行!
--package.loaded["脚本名"] --=>返回boolean 代表该脚本是否被加载并执行
print(package.loaded["Test114514"]) --=> true
--卸载脚本
package.loaded["Test114514"] = nil
print(package.loaded["Test114514"]) --=> nil
require("Test114514") --=>重新加载并执行

大G表 _G(特殊的Table,存储所有申明的全局变量)

--*****大G表*****
-- _G表 是一个总表Table 它会存储所有申明的全局变量
-- 打印-G表
for k,v in pairs(_G) do
	print(k,v)
end
--局部变量 不会被存到_G表中

模拟三目运算符(利用 and 和 or 的短路特性)

x = 3
y = 2
--用 and 和 or 模拟三目运算符
local res = (x > y) and x or y;
print(res);

协程

--*********************协程的创建********************
fun = function()
	print(114514)
end

--create创建一个协程,本质是一个线程对象thread
co = coroutine.create(fun);
print(type(co)) --=> thread
print(co)

--wrap创建的协程是一个function
co2 = coroutine.wrap(fun)
print(type(co2)) --=> function
print(co2)


--使用resume调用协程(使用create创建的)
coroutine.resume(co)

--使用wrap创建的协程是function,所以可以直接调用
co2()
--*********************协程的创建********************


--*********************协程的挂起********************
print("*****协程的挂起*****")

func2 = function()
	local i = 1
	while true do
		print(i)
		i = i + 1

		print(coroutine.status(co3)) --=> running
		print(coroutine.running()) --=> 当前协程的线程号

		--协程的挂起函数,可以有返回值
		coroutine.yield(i)
	end
end

co3 = coroutine.create(func2)
--只会运行到coroutine.yield().即只运行了一次循环
--默认第一个返回值为协程是否启动成功,第二个参数开始为返回值
isOk,tempI = coroutine.resume(co3) --=> 1
isOk,tempI = coroutine.resume(co3) --=> 2
isOk,tempI = coroutine.resume(co3) --=> 3

co4 = coroutine.wrap(func2)
--wrap的协程的返回值没有默认的是否启动成功,直接为yield中的返回值
tempI = co4() --=> 1
print(tempI)
tempI = co4() --=> 2
print(tempI)
tempI = co4() --=> 3
print(tempI)
tempI = co4() --=> 4
print(tempI)
--*********************协程的挂起********************


--*********************协程的状态********************
print("*****协程的状态*****")
--coroutine.status(协程对象)
--dead 结束
--suspended 暂停
--running 运行中

--被挂起的协程外部会返回 suspended
--running只会在协程内部返回
--dead指协程运行结束或没有被挂起
print(coroutine.status(co3)) --=> suspended

--打印正在运行的协程的线程号,需要在协程内部调用
print(coroutine.running())
--*********************协程的挂起********************


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字

插入代码