【Lua热更新】上篇

news2025/4/15 16:43:02

Lua 热更新 - 上篇

下篇链接:【Lua热更新】下篇

文章目录

  • `Lua` 热更新 - 上篇
    • 一、`AssetBundle`
      • 1.理论
      • 2. AB包资源加载
    • 二、`Lua` 语法
      • 1. 简单数据类型
      • 2.字符串操作
      • 3.运算符
      • 4.条件分支语句
      • 5.循环语句
      • 6.函数
      • 7. table数组
      • 8.迭代器遍历
      • 9.复杂数据类型 - 表
        • 9.1字典
        • 9.2类
        • 9.3 表的公共操作
      • 多脚本执行
      • 10.协同程序
      • 11.元表
        • 11.1 index
        • 11.2 newindex
        • 11.3其他操作
      • 12.面向对象
        • 12.1封装
        • 12.2继承
        • 12.3多态
      • 12 .【重要】面向对象汇总
      • 13.自带库
      • 13.垃圾回收
    • 三、`XLua`热更新

一、AssetBundle

1.理论

  • AB包是什么:特定于平台的资产压缩包,有点类似压缩文件,资产包括一些模型、贴图、预设体、音效、材质球等等

  • AB包作用:Resoureces打包时只读无法修改,AB包存储位置可以自定义,压缩方式自定义,后期可以动态更新。AB包可以减少包体大小,压缩资源减少初始包大小。可以通过热更新更新脚本或者资源

  • 使用

    在这里插入图片描述

2. AB包资源加载

  • 同步加载
// 加载AB包
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/model");
// 加载AB包中资源
// 通过泛型加载
GameObject cube = ab.LoadAsset<GameObject>("cube");
// 通过type加载
GameObject sphere = ab.LoadAsset("sphere", typeof(GameObject)) as GameObject;
// AB包不能加载两次会报错
// AssetBundle ab2 = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/model");
  • 异步加载
public Image img;
IEnumerator LoadABRes(string abName, string resNAme)
{
    // 异步加载ab包
    AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Application.streamingAssetsPath + "/" + abName + "." + resNAme);
    yield return abcr;
    AssetBundleRequest abq = abcr.assetBundle.LoadAssetAsync(resNAme, typeof(Sprite));
    yield return abq;
    img.sprite = abq.asset as Sprite;
}
  • AB包卸载
AssetBundle ab2 = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/model");
// 卸载所有AB包
// true会把场景上加载的AB包资源也卸载了
AssetBundle.UnloadAllAssetBundles(false);
// 卸载单独的AB包
ab2.Unload(false);

二、Lua 语法

1. 简单数据类型

  • lua所有变量声明不需要申明变量类型
  • lua可以改变数据类型,自动识别
  • 通过type函数获得类型
  • lua中使用未声明的变量默认是nil
-- 【nil类型】:类似 C#中的null
a = nil
print(a)
print(type(a))

-- 【number类型】:表示所有数值类型
a = 1
print(a)
print(type(a))
a = 10.2
print(a)
print(type(a))

-- 【string类型】:字符串类型,lua中单引号或双引号都是字符串与C#中不同,lua中没有char
a = "123"
print(a)
a = '111'
print(a)
print(type(a))

-- 【boolean类型】
a = true
print(a)
print(type(a))

2.字符串操作

  • lua中文占三个字符
-- 获得字符串长度
str = "hellowrold"
print(#str)
str = "你好"
print(#str)

-- 字符串拼接
print("你好".."世界")
print(string.format("我%d岁了", 18))

-- 转字符串
str = tostring(true)
print(str)

-- 字符串转ASCII码
a = string.byte("Lua", 1)
print(a)
-- ASCII码转字符
str = string.char(a)
print(str)

3.运算符

  • 字符串可以自动转成number
  • 整数相除可以转换为浮点数
  • 不支持自增自减++ –
  • 不支持位运算、三目运算符
  • Luanilfalse 才是假
  • lua中逻辑运算符支持短路
-- 算数运算符
print("3.14" + 2) -- 输出5.14
print(3 / 2) -- 输出1.5
print(2 ^ 2) -- 支持幂运算

-- 条件运算符
print(100 ~= 5) -- 不等于符号,与C#不同(!= )

-- 逻辑运算符
-- lua中逻辑运算符支持短路
print(true and false) -- &&与
print(true or false) -- ||或
print(not true) -- !非
-- lua中and or可以链接任意类型
print(1 and 2) -- 返回 2
print(nil and 1) -- 返回 nil
-- 使用逻辑运算模拟三目运算符
res = (x > y) and x or y

4.条件分支语句

  • 不支持switch
a = 6
-- if 语句
if a > 5 then
	print("success!")
end

-- if-else语句
if a > 5 then
	print("succcess!")
else
	print("fault!")
end

-- if-else if语句
if a == 5 then
	print("是5!")
elseif a == 6 then
	print("是6!")
end

5.循环语句

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

-- do while
num = 6
repeat
	num = num + 1
until num > 5
print(num)

-- for
-- for 变量, 结束值,增量值(省略默认为1)
for i = 1, 5, 2 do
	print(i)
end

6.函数

-- 1.1声明
function myFirstFun()
	print("我的第一个函数")
end
-- 调用
myFirstFun()

-- 2.1有参函数
function testFun1(name)
	print("我的名字是"..name)
end
testFun1("小猫")

-- 3.1有返回值函数
-- 3.1.1一个返回值
function testFun2()
	return "yes"
end
temp = testFun2()
print(temp)
-- 3.1.2多个返回值
function testFun3()
	return "paramete1","paramete2"
end
temp1, temp2 = testFun3()
print(temp1..temp2)

-- 4.1类型
-- 不用写函数名
func1 = function()
	print("这是一个函数")
end
print(type(func1))
func1()

-- 5.1变长参数
function testFun4(...)
	arg = {...}
	for i = 1, #arg do
		print(arg[i])
	end
end
testFun4(1, 2, 3)

-- 6.1函数嵌套
-- 闭包情况
function myFunC(x)
	return function(y)
		return x + y
	end
end

myfunc = myFunC(1)
ans = myfunc(2)
print("ans = "..ans)

7. table数组

  • lua中下标从1开始,越界读取最后一个
  • 表中存在nil会打断表长
-- 1.1 数组声明
a = {1, 2, true, "name", nil}
print(a[1]) -- 下标从1开始
print(#a) -- 输出:4

-- 1.2 多维数组
a = {{1, 2, 3}, {4, 5, 6, 7}}
print(a[1][1])
for i = 1, #a do
	b = a[i]
	for j = 1, #b do
		print(b[j])
	end
end

8.迭代器遍历

  • pairs遍历所有都能获得建议使用
a = {[0] = 1, 2, [-1] = 3, 4, 5}

-- 1.1 ipairs遍历
-- 只能找从1开始下标,小于等于0得不到
-- 只能找连续索引的,如果中断后面无法获得
for k, v in ipairs(a) do
	print("key = "..k.." value = ".. v)
end

-- 1.2 pairs遍历
-- 所有都能获得
for k, v in pairs(a) do
	print("key = "..k.." value = ".. v)
end
-- 只遍历键
for k in pairs(a) do
	print("key = "..k)
end

9.复杂数据类型 - 表

9.1字典
fruitDic = {["apple"] = 10, ["banana"] = 5}
print(fruitDic["apple"])
print(fruitDic.banana) -- 只有字符串可以通过.获得

-- 遍历
for k, v in pairs(fruitDic) do
	print(k,v) -- 传入多个参数print
end
9.2类
  • lua中不存在面向对象
student = {
	name = "lily",
	age = 10,
	sex = true,
	changeSex = function(v)
		student.sex = v
	end,
	printSex = function()
		print(student.sex)
	end,
	printName = function(m)
		print(m.name)
	end
}

student.printSex()
student.changeSex(false)
student.printSex()

-- 冒号调用
-- 冒号调用默认第一个参数是调用者
-- .调用不能
student:printName()

-- 外部添加函数
-- 方法一:
function student.myScore(v)
	print(v + 100)
end

-- slef表示默认传入的第一个参数
-- 方法二:
function student:printAge()
	print(self.age)
end
-- 冒号声明冒号调用
student:printAge()
9.3 表的公共操作
t1 = {{name = "小猫", age = 1}, {name = "小狗", age = 2}}
t2 = {name = "小鸟", age = 2}

-- 1.1插入
-- t2 插入到 t1 中
table.insert(t1, t2)
print(#t1)

-- 1.2删除
-- 删除 t1 的最后一个元素
table.remove(t1)
print(t1[2].name)
-- 删除指定下标
table.remove(t1, 1)
print(t1[1].name)

-- 1.3排序
t = {5, 6, 1, 3, 9, 2}

-- 默认升序
table.sort(t)
print("----降序-----")
for _,v in pairs(t) do
	print(v)
end

-- 降序
table.sort( t, function(a, b)
	return a > b
end )
print("----降序-----")
for _,v in pairs(t) do
	print(v)
end

-- 1.4 拼接
tb = {"ccc", "aaa", "bbb"}
str = table.concat( tb, ";")
print(str)

多脚本执行

-- 1.1 局部变量
function myFunC()
	local x = 1
	y = 1
end

myFunC()
print(x) -- x是局部变量
print(y) -- y是全局变量

-- 1.2 多脚本执行
-- require("脚本名") 执行其他脚本,只能加载一次
require("testLua")
-- 获得其他脚本的全局变量,局部变量获取不到
print(myTest)

-- 1.3脚本卸载
-- 脚本是否被加载过
isLoad = package.loaded["testLua"]
print(isLoad)
-- 卸载脚本
package.loaded["testLua"] = nil

-- 1.4 大G表
-- 大G表是一个总的table表,存储了所有全局变量在里面
for k,v in pairs(_G) do
	print(k, v)
end

在这里插入图片描述

require 脚本可以 return 一个数据返回出去得到

10.协同程序

fun = function()
	print("使用协程")
	local i = 1
	while true do
		print(i)
		i = i + 1
		coroutine.yield(i)
	end
end

-- 返回一个线程
co = coroutine.create(fun)
print("类型:"..type(co))
coroutine.resume(co) -- 输出1
isOK, temp1 = coroutine.resume(co) -- 输出2
print(isOK,temp1) -- 第一个参数返回协程状态,第二个参数返回协程返回值

-- 返回的是函数
co2 = coroutine.wrap(fun)
print("类型:"..type(co2))
co2() -- 输出1
temp1 = co2() -- 输出2
print(temp1) -- 直接返回协程返回值

-- 获得协程状态
-- 传入协程对象,返回状态:dead结束 susdeaded暂停 running进行
back = coroutine.status(co)
print(back)

11.元表

11.1 index
  • index取值时,使用当子表中找不到某属性时会到元素中__index指定的表去查找索引
  • index支持向上查找原表的index
meta = {
	name = "father",
	age = 10,
}
sonTable = {
	name = "son"
}
setmetatable(sonTable, meta)
print(sonTable.age) -- 输出 nil

-- 设置__index
meta.__index = meta
print(sonTable.age) -- 输出 10
11.2 newindex
  • newindex当赋值时,如果赋值不存在索引,将会赋值到newindex所指向的表中
meta = {
	name = "father"
}
sonTable = {
}
setmetatable(sonTable, meta)

sonTable.name = "son"
print(sonTable.name) -- 输出son

meta.__newindex = {}
print(sonTable.age) -- 输出nil
11.3其他操作
meta = {
	name = "father",
	__tostring = function(t)
		return t.name
	end,
	__call = function(t)
		print(t)
		print("call!")
	end,
	__add = function(t1, t2)
		return t1.name..t2.name
	end
}
sonTable = {
	name = "son"
}

-- 设置元表:参数一 子表 参数二 元表
setmetatable(sonTable, meta)

-- 1.1 __tostring
-- 当子表被当作字符串使用时会调用tostring方法
-- 默认传递第一个参数为调用者自己
print(sonTable)-- 输出son

-- 1.2 __call
-- 子表被当作函数使用时会调用call方法
-- 默认传递第一个参数为调用者自己
sonTable() -- 输出 son call!

-- 1.3运算符重载
-- __add 加法
print(sonTable + meta) -- 输出sonfather
-- __sub 减法、__mul 乘法、 __div 除法、 __mod 取余、 __pow 幂、 
-- __eq  相等== 原表一致返回true、__lt  小于、 __le  小于等于、__concat 拼接

12.面向对象

12.1封装
-- 1.1 封装
Object = {}
Object.id = 1

-- 冒号调用,默认使用调用者作为第一个参数
function Object : new()
	-- self,获得默认传入的第一个参数
	-- 返回一个新对象(表),使用局部变量
	-- 设置对象的元表,和__index
	local obj = {}
	self.__index = self
	setmetatable(obj, self)
	return obj
end

local my = Object : new()
print(my.id) -- 输出1,因为使用了__index

my.id = 99
print(my.id) -- 输出99,没有使用__newindex不会改变元表
print(Object.id) -- 输出1

-- 封装一个函数
function Object : TestFun()
	print(self.id)
end

my:TestFun() -- 输出99
Object:TestFun() -- 输出1
12.2继承
-- 为父类写一个继承方法
function Object : subClass(className)
	-- _G表,是一个总表存储所有声明了的全局变量,以键值对形式存储
	-- 在_G中创建一个表
	_G[className] = {}
	-- 用元表完成继承
	local obj = _G[className]
	self.__index = self
	setmetatable(obj, self)
end

-- Person继承Object
Object:subClass("Person")
-- 使用Object中的new对象方法
local p1 = Person:new()
print(p1.id)
12.3多态

在这里插入图片描述

-- Entity 继承 Object
Object : subClass("Entity")
-- 为 Object 添加变量和方法
Object.Speed = 0
function Object : GetSpeed()
	print("这是Object的方法")
	self.Speed = self.Speed + 1
	print(self.Speed)
	return self.Speed
end

-- Player 继承 Entity
Entity : subClass("Player")

-- 创建Player 对象 p1
local p1 = Player:new()
p1:GetSpeed() -- 输出:这是Object的方法

-- 子类Player重写方法
function Player : GetSpeed()
	print("这是Player重写的方法")
	return self.Speed
end
p1:GetSpeed() -- 输出:这是Player重写的方法

-- 构建base保留父类方法调用 : 如图

-- 创建Player 对象 p2
local p2 = Player:new()
p2:GetSpeed() -- 输出:这是Player重写的方法

-- 【注意】有误的
p1.base:GetSpeed() -- 输出:Speed = 1
p2.base:GetSpeed() -- 输出:Speed = 2
-- 【注意】正确的,使用点调用否则使用的是父类的变量
function Player : GetSpeed()
	self.base.GetSpeed(self)
end
p1:GetSpeed()
p2:GetSpeed()
-- 或者
p1.base.GetSpeed(p1)
p2.base.GetSpeed(p2)

12 .【重要】面向对象汇总

-- 基类
Object = {}
-- 实例化对象方法
function Object : new()
	local obj = {}
	self.__index = self
	setmetatable(obj, self)
	return obj
end
-- 继承方法
-- className:类名(字符串)
function Object : subClass(className)
	_G[className] = {}
	local obj = _G[className]
	self.__index = self
	obj.base = self
	setmetatable(obj, self)
end

13.自带库

-- 时间
-- 系统时间
print(os.time())
print(os.time({year = 2024, month = 12, day = 17}))
local nowTime = os.date("*t")
for k, v in pairs(nowTime) do
	print(k, v)
end

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

-- 路径
print(package.path)

13.垃圾回收

三、XLua热更新

下篇链接:【Lua热更新】下篇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2263817.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AJAX与Axios

什么是 AJAX ? AJAX 是异步的 JavaScript 和 XML&#xff08;Asynchronous JavaScript And XML&#xff09;。 简单理解AJAX&#xff1a;是一种客户端与服务器进行网络通信技术&#xff0c;AJAX通常使用XMLHttpRequest 对象来发送请求和接收响应 现代开发中我们通常使用 JS…

1.gitlab 服务器搭建流程

前提条件&#xff1a; 一、服务器硬件水平 搭建gitlab服务器最低配置要求2核4G,低于这个配置的服务器运行效果很差。 gitlab官网&#xff1a;https://about.gitlab.com/ 下载地址&#xff1a;gitlab/gitlab-ce - Packages packages.gitlab.com 本机ubuntu 二、安装依赖 su…

springboot462学生心理压力咨询评判(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装学生心理压力咨询评判软件来发挥其高效地信息处理的作用&am…

git分支管理及策略

Git 的默认分支就是 master。你所作的commit会在master分支上自动移动。 在多次提交操作之后&#xff0c;master分支指向最后那个commit object&#xff08;提交对象链&#xff09;。 Git 的 “master” 分支并特殊&#xff0c;跟其它分支没有区别。 之所以几乎每一个仓库都有…

python中wb有什么用

‘wb’&#xff1a;表示以二进制写方式打开&#xff0c;只能写文件&#xff0c; 如果文件不存在&#xff0c;创建该文件&#xff1b;如果文件已存在&#xff0c;则覆盖写。 Python文件使用“wb”方式打开&#xff0c;写入字符串会报错&#xff0c;因为这种打开方式为&#xff…

Connecting to Oracle 11g Database in Python

# encoding: utf-8 # 版权所有 2024 涂聚文有限公司 # 许可信息查看&#xff1a;言語成了邀功盡責的功臣&#xff0c;還需要行爲每日來值班嗎 # 描述&#xff1a;python -m pip install oracledb # python -m pip install cx_Oracle --upgrade # pip install cx_Oracle # Autho…

学工管理系统-职校信息化管理平台

学工管理系统是一种致力于提升职校管理效率和信息化水平的重要工具。它综合运用了现代信息技术和学工管理理念&#xff0c;为学校提供了全面、科学、高效的管理平台。 学工管理系统在学校管理中发挥着重要的作用。它能够实现学生信息的完整管理&#xff0c;包括学籍、课程、成绩…

MySQL三大日志-Binlog

Binlog简介 Redo Log 是属于InnoDB引擎所特有的日志&#xff0c;而MySQL Server也有自己的日志&#xff0c;即 Binary log&#xff08;二进制日志&#xff09;&#xff0c;简称Binlog。Binlog是记录所有数据库表结构变更以及表数据修改的二进制日志&#xff0c;不会记录SELECT…

【Token】校验、会话技术、登录请求、拦截器【期末实训】实战项目学生和班级管理系统\Day15-后端Web实战(登录认证)\讲义

登录认证 在前面的课程中&#xff0c;我们已经实现了部门管理、员工管理的基本功能&#xff0c;但是大家会发现&#xff0c;我们并没有登录&#xff0c;就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的&#xff0c;所以我们今天的主题就是登录认证。 最终我们要实现…

物联网:全面概述、架构、应用、仿真工具、挑战和未来方向

中文论文标题&#xff1a;物联网&#xff1a;全面概述、架构、应用、仿真工具、挑战和未来方向 英文论文标题&#xff1a;Internet of Things: a comprehensive overview, architectures, applications, simulation tools, challenges and future directions 作者信息&#x…

实验13 C语言连接和操作MySQL数据库

一、安装MySQL 1、使用包管理器安装MySQL sudo apt update sudo apt install mysql-server2、启动MySQL服务&#xff1a; sudo systemctl start mysql3、检查MySQL服务状态&#xff1a; sudo systemctl status mysql二、安装MySQL开发库 sudo apt-get install libmysqlcli…

将4G太阳能无线监控的视频接入电子监控大屏,要考虑哪些方面?

随着科技的飞速发展&#xff0c;4G太阳能无线监控系统以其独特的优势在远程监控领域脱颖而出。这种系统结合了太阳能供电的环保特性和4G无线传输的便捷性&#xff0c;为各种环境尤其是无电或电网不稳定的地区提供了一种高效、可靠的视频监控解决方案。将这些视频流接入大屏显示…

在uniapp Vue3版本中如何解决webH5网页浏览器跨域的问题

问题复现 uniapp项目在浏览器运行&#xff0c;有可能调用某些接口会出现跨域问题&#xff0c;报错如下图所示&#xff1a; 什么是跨域&#xff1f; 存在跨域问题的原因是因为浏览器的同源策略&#xff0c;也就是说前端无法直接发起跨域请求。同源策略是一个基础的安全策略&a…

自毁程序密码—阿里聚安全(IDA动态调试)

App信息 包名&#xff1a;com.yaotong.crackme Java层分析 MainActivity 很容易就能看出来是在securityCheck函数里进行安全校验。securityCheck是一个native函数&#xff0c;到so中进行分析。 SO层分析 定位函数位置 在导出函数里搜索 securityCheck 数据类型修复和…

使用国内镜像网站在线下载安装Qt(解决官网慢的问题)——Qt

国内镜像网站 中国科学技术大学&#xff1a;http://mirrors.ustc.edu.cn/qtproject/清华大学&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/qt/北京理工大学&#xff1a;http://mirror.bit.edu.cn/qtproject/ 南京大学&#xff1a;https://mirror.nju.edu.cn/qt腾讯镜像&…

蓝桥杯刷题——day8

蓝桥杯刷题——day8 题目一题干解题思路代码 题目二题干解题思路代码 题目一 题干 N 架飞机准备降落到某个只有一条跑道的机场。其中第i架飞机在 Ti时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 Di个单位时间&#xff0c;即它最早可以于 Ti时刻开始降落&am…

大数据-256 离线数仓 - Atlas 数据仓库元数据管理 正式安装 启动服务访问 Hive血缘关系导入

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

Mysql中的排序与分页

1. 排序数据 1.1 排序规则 使用 ORDER BY 子句排序 ASC&#xff08;ascend&#xff09;: 升序 DESC&#xff08;descend&#xff09;:降序 ORDER BY 子句在SELECT语句的结尾。 1.2 单列排序 1.3 多列排序 可以使用不在SELECT列表中的列排序。 在对多列进行排序的时候&a…

CS!GO

CS&#xff08;computer science&#xff09;计算机科学&#xff0c;说实话&#xff0c;不是找工作面试&#xff0c;这些题谁会背啊&#xff0c;反正我不行&#xff0c;一问三不知。 咱也不管这些&#xff0c;这个系列&#xff0c;可能会时不时的给出一些计网和操作系统相关的东…

【MAC】深入浅出 Homebrew 下 Nginx 的安装与配置指南

硬件&#xff1a;Apple M4 Pro 16寸 系统&#xff1a; macos Sonoma 15.1.1 Nginx 是一款高性能的 Web 服务器和反向代理服务器&#xff0c;广泛应用于全球各地的网站和企业应用中。本文将详细介绍如何在 macOS 环境下使用 Homebrew 安装、启动、管理以及优化配置 Nginx&#x…