[unity]lua热更新——个人复习笔记【侵删/有不足之处欢迎斧正】

一、AssetBundle

AB包是特定于平台的资产压缩包,类似于压缩文件

相对于RESOURCES下的资源,AB包更加灵活轻量化,用于减小包体大小和热更新

可以在unity2019环境中直接下载Asset Bundle Browser

可以在其中设置关联

AB包生成的文件

AB包文件:资源文件
manifest文件:AB包文件信息;当加载时,提供了关键信息,资源信息,依赖关系,版本信息等等
关键AB包(和目录名一样的包 )

AB包资源加载

void Start(){
//加载AB包
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath+"/"+"model");//加载AB包中的资源
//只用名字加载那么会出现同名同类型资源混乱
GameObject obj = ab.LoadAsset<GameObject>("Cube");}

AB包依赖

关于AB包的依赖一一个资源身 上用到了别的AB包中的资源这个时候如果只加载自己的AB包,通过它创建对象会出现资源丢失的情况,这种时候需要把依赖包-起加载了才能正常

可以考虑利用主包获取信息

//加载AB包
AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath+"/"+"model");//加载主包和其中的固定文件
AssetBundle abMain = AssetBundle.LoadFromFile(Application.streamingAssetsPath +"/"+"PC");
AssetBundleManifest abManifest=abMain.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

AB包资源加载管理器

public class ABMgr : SingletonAutoMono<ABMgr>
{//主包private AssetBundle mainAB = null;//主包依赖获取配置文件private AssetBundleManifest manifest = null;//选择存储 AB包的容器//AB包不能够重复加载 否则会报错//字典知识 用来存储 AB包对象private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();private string PathUrl{get{return Application.streamingAssetsPath + "/";}}private string MainName{get{
#if UNITY_IOSreturn "IOS";
#elif UNITY_ANDROIDreturn "Android";
#elsereturn "PC";
#endif}}private void LoadMainAB(){if( mainAB == null ){mainAB = AssetBundle.LoadFromFile( PathUrl + MainName);manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");}}private void LoadDependencies(string abName){//加载主包LoadMainAB();//获取依赖包string[] strs = manifest.GetAllDependencies(abName);for (int i = 0; i < strs.Length; i++){if (!abDic.ContainsKey(strs[i])){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + strs[i]);abDic.Add(strs[i], ab);}}}public T LoadRes<T>(string abName, string resName) where T:Object{//加载依赖包LoadDependencies(abName);//加载目标包if ( !abDic.ContainsKey(abName) ){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//得到加载出来的资源T obj = abDic[abName].LoadAsset<T>(resName);//如果是GameObject 因为GameObject 100%都是需要实例化的//所以我们直接实例化if (obj is GameObject)return Instantiate(obj);elsereturn obj;}public Object LoadRes(string abName, string resName, System.Type type) {//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//得到加载出来的资源Object obj = abDic[abName].LoadAsset(resName, type);//如果是GameObject 因为GameObject 100%都是需要实例化的//所以我们直接实例化if (obj is GameObject)return Instantiate(obj);elsereturn obj;}public Object LoadRes(string abName, string resName){//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//得到加载出来的资源Object obj = abDic[abName].LoadAsset(resName);//如果是GameObject 因为GameObject 100%都是需要实例化的//所以我们直接实例化if (obj is GameObject)return Instantiate(obj);elsereturn obj;}public void LoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T:Object{StartCoroutine(ReallyLoadResAsync<T>(abName, resName, callBack));}//正儿八经的 协程函数private IEnumerator ReallyLoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object{//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//异步加载包中资源AssetBundleRequest abq = abDic[abName].LoadAssetAsync<T>(resName);yield return abq;if (abq.asset is GameObject)callBack(Instantiate(abq.asset) as T);elsecallBack(abq.asset as T);}public void LoadResAsync(string abName, string resName, System.Type type, UnityAction<Object> callBack){StartCoroutine(ReallyLoadResAsync(abName, resName, type, callBack));}private IEnumerator ReallyLoadResAsync(string abName, string resName, System.Type type, UnityAction<Object> callBack){//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//异步加载包中资源AssetBundleRequest abq = abDic[abName].LoadAssetAsync(resName, type);yield return abq;if (abq.asset is GameObject)callBack(Instantiate(abq.asset));elsecallBack(abq.asset);}public void LoadResAsync(string abName, string resName, UnityAction<Object> callBack){StartCoroutine(ReallyLoadResAsync(abName, resName, callBack));}private IEnumerator ReallyLoadResAsync(string abName, string resName, UnityAction<Object> callBack){//加载依赖包LoadDependencies(abName);//加载目标包if (!abDic.ContainsKey(abName)){AssetBundle ab = AssetBundle.LoadFromFile(PathUrl + abName);abDic.Add(abName, ab);}//异步加载包中资源AssetBundleRequest abq = abDic[abName].LoadAssetAsync(resName);yield return abq;if (abq.asset is GameObject)callBack(Instantiate(abq.asset));elsecallBack(abq.asset);}//卸载AB包的方法public void UnLoadAB(string name){if( abDic.ContainsKey(name) ){abDic[name].Unload(false);abDic.Remove(name);}}//清空AB包的方法public void ClearAB(){AssetBundle.UnloadAllAssetBundles(false);abDic.Clear();//卸载主包mainAB = null;}
}

二、lua基础语法

第一个lua程序

print("你好世界");
--单行注释
--lua语句可以省略分号--[[
多行数据
]]--[[
多行数据
]]----[[
还是多行数据
--]]

lua的变量(lua中所有的变量声明都不需要申明类型,会自动的判断类型)

简单变量类型:nil number string boolean

nil 相当于空的概念

number 所有的数值都是number(lua中的一个变量可以随便赋值)

string 字符串类型,字符串的声明需要用单双引号包裹,lua中无char类型

boolean 真或假

可以通过type获得变量类型,其返回值是string类型

注意:lua中使用没有声明过的变量不会报错,其值是空

其他数据类型:function table userdata thread

字符串操作

s="5464565655"print(#s)
--获取字符串长度
--中文字符在lua中占三个长度
--多行打印
--lua中支持转义字符
print("123\n123")s =[[hello
world
]]
--字符串拼接
print("1323".."65456")

注意lua字符串索引开始都是从1开始的,而不是从0开始

 运算符

算术运算符:+-*/%^

与c#中基本相同,但是需要注意lua中无++ -- += *= %= -=

(字符串可以进行算数运算符的惭怍 会自动转成number)

lua中^是幂运算

条件运算符:> < <= == ~=

~= Lua中的不等于 相当于C#中的!=

逻辑运算符

&&  ||  (c#)

and or  (lua)

not  取反

lua中and和or支持短路原则

位运算符(不支持)

三目运算符(不支持)

条件分支语句

print("条件分支语句")-- if  条件 then ... end
if a > 6 thenprint("666")
elseif  a == 999 thenprint("123")
elseprint("555")
end

在lua中没有switch语句

循环语句

num = 0
--while
while num <555 doprint(num)num =num +1
end--do  while
repeatprint(num)
until num>555
--满足条件跳出,不同于C#中的进入条件--for语句
for i =1,5 doprint(i)
end
for i =1,5,2 doprint(i)
end

函数

function 函数名()

end

不同于c#,函数在声明之前,不能调用

无参无返回值

F2 = function()print("F1hanshu")
end
F2()

有参有返回值

F2 = function(a)print(a)
end
F2(1)
F2()
--不传参数,默认为空

如果传入的参数和函数参数个数不匹配,不会报错,只会补nil或者丢弃参数

F2 = function(a)return a ,"123",false
end
tt = F2(a)

多返回值时,在前面申明多个变量来截取,变量不够会接取对应位置的返回值

函数的类型

F2 = function()print("F1hanshu")
end
F2()
print(type(F2))

函数的重载

LUA中不支持函数的重载

变长参数

F2 = function(...)print("F1hanshu")
end
F2()

变长参数使用 先用一个表存起来 再来使用

函数嵌套

F2 = function()F6 =function()print(666);endreturn F9 print("F1hanshu")
endf9 =F2()
f9()

table表实现数组

所有的复杂类型本质上都是Table

数组:

a ={1,2,3,true,nil,"9916"}
print(a[1])
--lua中的索引从1开始

获取数组长度

--#是通用的获取长度的关键字
--在打印长度时,nil和其数组后面的数据将会被省略

自定义索引:

aa ={[0]=1,2,3,[-5]=4,5}
print(aa[-5])
print(#aa)
--输出为4 3

 迭代器遍历

主要是用于遍历表

#得到的长度,其实是不准确的 一般不会使用#来遍历表

aa ={[0]=1,2,3,[-5]=4,5}
--ipairs
for i ,k in ipairs(aa) doprint(i..k)
end

ipairs遍历还是从1开始遍历,小于等于0的值得不到,只能找到连续连续索引的键值

aa ={[0]=1,2,3,[-5]=4,5}
--pairs
for i ,v in pairs(aa) doprint(i..v)
end
--能把所有键都找到 通过键找到值

table表现字典

--字典的声明
a = {["name"]="Name",["anme"]=5}
print(a["name"])
--还可以类似.成员变量的形式得到值,但是不能是数字
print(a.name)--字典新增
a["newnew"]=666--模拟字典 遍历一定要使用pairs
for k,v in pairs(a) do--可以穿多个参数 一样可以打印出来print(k,v)
endfor _,v in pairs(a) do--遍历值print(v)
end

table实现类

lua中默认没有面向对象,需要自己去实现

Student ={age =1,sex=true,Up=function function_name(  )-- bodyprint("函数")end}print(Student.age)
Student.Up()

lua中.和:的区别在于,:调用方法时,会默认把调用者作为第一个参数传入方法中

表的公共操作

a = {{age =1 ,name ="123"},{age =2 ,name="456"}}
b={name ="54645",sex=false}--插入
table.insert(a,b);
--在a表中加入b--删除指定元素
--移除最后一个索引的内容
table.remove(a)--排序算法
t={5,9,54,5,7}
table.sort(t)

多脚本执行

全局变量与本地变量

--全局变量与本地变量
a = 1
b = 1
--以上都是全局变量for i=1,2 doc=1
end--c还是全局变量--本地变量的关键字是 local
fun =function()tt="123123"
end
fun()
print(tt)--能正常输出,是全局变量

多脚本执行

全局变量,只要执行过后,可以在任何脚本中进行调用

脚本卸载

如果是require("")加载执行的脚本,加载一次过后不会再执行

可以利用package.loaded["脚本名"]来判断脚本是否被执行

大G表

是一个总表,将我们声明的全部全局变量都储存在其中,本地变量不会存储

LUA的特殊用法

多变量赋值

l,g,c = 1 ,2 ,true
l,g,c=1,2
--多变量赋值后面的值不够会自动补空,多了会自动省略

多返回值

function Test()return 10,20,30
end
a,b,c =Test()

and 与 or

在lua中只有 nil 和 false才会被认为是假

lua模拟三目运算符

local res = (x>y) and x or b

协同程序

--coroutine.create()
fun = function()print(123)
end
--协程本质上是一个线程对象
lu=coroutine.create(fun)--coroutine.wrap()
ji = coroutine.wrap(fun)--协程运行
coroutine.resume(lu)
ji()--协程的挂起
fun2=function()while true doprint(123)--挂起函数coroutine.yield()end
endpeng =coroutine.create(fun2)
coroutine.resume(peng)

元表

任何表对象都可以作为另一个表变量的元表

当对子表中进行特定操作时,会执行元表中的内容

mega = {--当子表要被当作字符串使用时,会默认调用元表中的tostring方法__tostring =function(t)return t.nameend,--当子表被当作一个函数使用时,会默认调用__call中的内容__call =function(a,b)print(a)print(b)--默认第一个参数是调用自己end
}
myMega = {name = "666"
}
--设置元表函数
--第一个为子表,第二个为夫表
setmetatable(myMega,mega)print(myMega)

LUA自带库

--系统时间
print(os.time())
print(os.time({year=2014,month=8,day=14}))local nowTime =os.data("*t")
--可以得到更多的信息--数学运算
print(math.abs(-1555))--弧度转角度
print(math.deg(math.pi))--向下取整
print(math.floor(-1555))--最小值
print(math.min(-1555,999))--小数分离
print(math.modf(1.5555))--随机数
math.randomseed(os.time())
print(math.random(100))--路径
print(package.path)
--打印LUA脚本加载路径

垃圾回收

--垃圾回收
lu={id=1,idd=2}
collectgarbage("count")
--获取当前lua占用内存数,返回千字节单位--进行垃圾回收
collectgarbage("collect")
print(collectgarbage("count"))--lua的垃圾回收机制和c#中类似,取消羁绊便成为垃圾--lua中有自动计时垃圾回收的方法,但不推荐在项目中使用

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

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

相关文章

【Linux】云服务器的Redis被黑

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Linux ⛺️稳中求进&#xff0c;晒太阳 攻击发现&#xff1a; 这个异常情况是在腾讯云被入侵后&#xff0c;短信提醒发现的。并没有系统的学习过关于服务器安防相关的知识&#xff0c;遇到…

国产动漫|基于Springboot的国产动漫网站设计与实现(源码+数据库+文档)

国产动漫网站目录 目录 基于Springboot的国产动漫网站设计与实现 一、前言 二、系统功能设计 三、系统功能设计 1、用户信息管理 2、国漫先驱管理 3、国漫之最管理 4、公告信息管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题…

C语言中如何进行内存管理

主页&#xff1a;17_Kevin-CSDN博客 收录专栏&#xff1a;《C语言》 C语言是一种强大而灵活的编程语言&#xff0c;但与其他高级语言不同&#xff0c;它要求程序员自己负责内存的管理。正确的内存管理对于程序的性能和稳定性至关重要。 一、引言 C 语言是一门广泛使用的编程语…

VPX基于全国产飞腾FT-2000+/64核+复旦微FPGA的计算刀片

6U VPX计算板 产品简介 产品特点 飞腾计算平台&#xff0c;国产化率100% VPX-MPU6902是一款基于飞腾FT-2000/64核的计算刀片&#xff0c;主频2.2GHz&#xff0c;负责业务数据流的管控和调度。搭配自带独立显示芯片的飞腾X100芯片&#xff0c;可用于于各类终端及服务器类应用场…

spring boot整合cache使用memcached

之前讲了 spring boot 整合 cache 做 simple redis Ehcache 三种工具的缓存 上文 windows系统下载安装 memcached 我们装了memcached 但spring boot没有将它的整合纳入进来 那么 我们就要自己来处理客户端 java历史上 有过三种客户端 那么 我们用肯定是用最好的 Xmemcached …

vue2 + axios + mock.js封装过程,包含mock.js获取数据时报404状态的解决记录,带图文,超详细!!!

vue axios mock.js 以下是封装的过程&#xff0c;记录一下 1、首先先了解什么是mock.js的用途及特点 官网地址&#xff1a;Mock.js (mockjs.com) 作用&#xff1a;生成随机数据&#xff0c;拦截 Ajax 请求 优势&#xff1a; 2、了解axios的原理及使用 官网地址&#xff1a…

大模型(LLM)的token学习记录-I

文章目录 基本概念什么是token?如何理解token的长度&#xff1f;使用openai tokenizer 观察token的相关信息open ai的模型 token的特点token如何映射到数值&#xff1f;token级操作&#xff1a;精确地操作文本token 设计的局限性 tokenizationtoken 数量对LLM 的影响训练模型参…

研发日记,MatlabSimulink开箱报告(九)——Simulink Test模块

文章目录 前言 Simulink Test模块 静态测试 动态测试 逻辑测试 前言 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;四&#xff09;——S-Fuction模块》 见《开箱报告&#xff0c;Simulink Toolbox库模块使用指南&#xff08;五&#xff09;——S-F…

练习 2 Web [ACTF2020 新生赛]BackupFile 1

[ACTF2020 新生赛]BackupFile 1 Web常规题目 首先尝试查找常见的前端页面index.php之类的&#xff0c;没找到 题目有个“BackupFile”——备份文件 尝试用工具遍历查找相关的文件 御剑没扫出来&#xff0c;搜索搭建好dirsearch后&#xff0c;扫出来的index.php.bak 扫描工…

迟到的VNCTF2024逆向题WP

这次比赛因为有事外出&#xff0c;只做了前两题&#xff0c;最近有空才把另外3题也做出来&#xff0c;总体来说比以往的VNCTF逆向题目要难一些。当然也有可能是我水平退步了&#xff0c;就算有时间参加比赛&#xff0c;应该也做不完这5题。VN的小伙伴越来越厉害了&#xff0c;出…

猜猜心里数字(个人学习笔记黑马学习)

1.定义一个变量&#xff0c;数字类型&#xff0c;内容随意 2.基于input语句输入猜想的数字&#xff0c;通过if和多次elif的组合&#xff0c;判断猜想数字是否和心里数字一致 num5if int(input("请输入第一次猜想的数字&#xff1a;"))5:print("猜对了&#xff0…

ROS 2基础概念#1:计算图(Compute Graph)| ROS 2学习笔记

在ROS中&#xff0c;计算图&#xff08;ROS Compute Graph&#xff09;是一个核心概念&#xff0c;它描述了ROS节点之间的数据流动和通信方式。它不仅仅是一个通信网络&#xff0c;它也反映了ROS设计哲学的核心——灵活性、模块化和可重用性。通过细致探讨计算图的高级特性和实…

Java中使用Jsoup实现网页内容爬取与Html内容解析并使用EasyExcel实现导出为Excel文件

场景 Pythont通过request以及BeautifulSoup爬取几千条情话&#xff1a; Pythont通过request以及BeautifulSoup爬取几千条情话_爬取情话-CSDN博客 Node-RED中使用html节点爬取HTML网页资料之爬取Node-RED的最新版本&#xff1a; Node-RED中使用html节点爬取HTML网页资料之爬…

远程服务器Ubuntu 18.04安装VNC远程桌面

一、安装vnc 1.安装图形化界面工具 # 安装过程中会弹窗让选择配置&#xff0c;选lightdm sudo apt install ubuntu-desktop sudo apt-get install gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal 2.安装vnc sudo apt-get install x11vnc3.安装LightD…

ifcplusplus 示例 函数中英文 对照分析

有需求&#xff0c;需要分析 ifc c渲染&#xff0c;分析完&#xff0c;有 230个函数&#xff0c;才能完成一个加载&#xff0c;3d加载真的是大工程&#xff01; 函数中英文对照表&#xff0c;方便 日后开发&#xff0c;整理思路顺畅&#xff01;&#xff01;&#xff01;&#…

线性规划基础

利用一个简单的实例来介绍什么事线性规划&#xff0c;假设如果有一家巧克力工厂需要生产两种不同类型的巧克力&#xff0c;分别是类型A和类型B&#xff0c;两种巧克力用到的原材料是一样的&#xff0c;都是使用牛奶和可可两种材料&#xff0c;主要的区别是在与这两种原料的配料…

C语言实现21点游戏【单人模式,双人模式,单-多电脑模式】,21点又名黑杰克(英文:Blackjack)

项目背景&#xff1a; 21点又名黑杰克&#xff08;英文&#xff1a;Blackjack&#xff09; &#xff0c;起源于法国&#xff0c;已流传到世界各地。21点&#xff0c;是一种使用扑克牌玩的赌博游戏。亦是唯一一种在赌场中可以在概率中战胜庄家的一种赌博游戏。 现在在世界各地…

k8s初始化报错 [ERROR CRI]: container runtime is not running: ......

一、环境参数 linux系统为centos7kubernetes版本为v1.28.2containerd版本为1.6.28 二、报错内容 执行初始化命令kubeadm init命令时报错&#xff0c;内容如下 error execution phase preflight: [preflight] Some fatal errors occurred:[ERROR CRI]: container runtime is…

C++观察者模式代码实例

文章目录 C观察者模式代码实例一C观察者模式代码实例二 C观察者模式代码实例一 下面是一个简单的C观察者模式的实现示例&#xff0c;这里仅给出核心代码框架&#xff0c;完整的工程应包含对应的头文件声明及必要的#include指令等。 // 观察者接口&#xff08;Observer&#x…

【Unity实战】UGUI和Z轴排序那点事儿

如果读者是从Unity 4.x时代过来的&#xff0c;可能都用过NGUI这个插件&#xff08;后来也是土匪成了正规军&#xff09;&#xff0c;NGUI一大特点是可以靠transform位移的Z值进行遮挡排序&#xff0c;然而这个事情在UGUI成了难题&#xff08;Sorting Layer、Inspector顺序等因素…