[Unity学习教程] Assets--unity资源映射

[复制链接]
查看677 | 回复0 | 2023-8-23 11:41:12 | 显示全部楼层 |阅读模式 来自 中国北京
参考文章:
浅谈Assets——Unity资源映射 - UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 (uwa4d.com)
什么是Assets

Assets目次



  • Assets
    Unity工程现实的资源目次,所有项目用到的资源、代码、配置、库等原始资源只有放置在这个文件夹才会被Unity认可和处置惩罚。
2、AssetBundles
抛开所有其它的理解,单从英文命名来看,这是一种捆绑包,是对Asset举行归档的格式,概念更趋向于我们使用Zip大概RAR等格式对资源大概目次举行压缩、加密、归档、存储等等。而区别就在于Zip等压缩格式是针对文件的,而AssetBundles则是针对Unity的Asset。但如果再转换一下概念来理解,实在Zip利用归档的是利用体系能辨认的文件,而AssetBundles利用归档的则是Unity能辨认的文件。这么理解,二者的作用险些是一致的。 


  • Library
    存放Unity处置惩罚完毕的资源,大部分的资源导入到Assets目次之后,还须要通过Unity转化成Unity认可的文件,转化后的文件会存储在这个目次。
  • Packages
    这个是2018以后新增的目次,用于管理Unity分离的packages组件。这个我在之前的知乎文章里有过阐述:Unity手游实战:从0开始SLG——Unity目次分布(Asset权限规划) - 知乎
 
AssetBundles是一个包罗了特殊平台、非代码情势Assets的归档文件。 
3、Unity资产 
我们把一个Asset叫做一个资产,可以理解为Unity可以或许辨认的文件。这里实在又包罗两种范例,一种是Unity原生支持的格式,比如:材质球;一种是须要颠末Unity处置惩罚之后才气支持的,比如:FBX。对于须要处置惩罚才气支持的格式,Unity都提供了导入器(Importer) 
二、Assets的辨认和引用 

1、Assets和Objects
在举行背面的阐述之前,先统逐一下概念,包罗如果在背面章节里提到,都会依照这里统一的概念。Assets这里以及后续的内容都指Unity的资产,可以意指为Unity的Projects窗口里看到的单个文件(大概文件夹)。而Objects这里我们指的是从UnityEngine.Object继承的对象,它实在是一个可以序列化的数据,用来形貌一个特定的资源的实例。它可以代表任何Unity引擎所支持的范例,比如:Mesh、Sprite、AudioClip or AnimationClip等等。
Assets和Objects之间是一对多的关系,比如一个Prefab我们可以以为是一个Asset,但是这个Prefab里可以包罗很多个Objects,比如:如果是一个UGUI的Prefab,里面就大概会有很多个Text、Button、Image等组件。
2、File GUIDs和Local IDs
熟悉Unity的人都知道,UnityEngine.Objects之间是可以互相引用的。这就会存在一个问题,这些互相引用的Objects有大概是在同一个Asset里,也有大概是在差别的Assets里。比如:UGUI的一个Image须要引用一张Sprite Atlas里的Sprite,这就要求Unity必须有健壮的资源标识,能稳定地处置惩罚差别资源的引用关系。除此之外,Unity还必须思量这些资源标识应该与平台无关,不能让开辟者在切换平台的时候还须要关注资源的引用关系,毕竟它本身是一个跨平台部署的引擎。
基于这些特定的需求,Unity把序列化拆分成两个表达部分。第一部分叫做File GUID,标识这个资产的位置,这个GUID是由Unity根据内部算法主动天生的,而且存放在原始文件的同目次、同名但是后缀为.meta的文件里。
这里须要注意几个点:


  • 第一次导入资源的时候Unity会主动天生。
  • 在Unity的面板里移动位置,Unity会主动帮你同步.meta文件。
  • 在Unity打开的情况下,单独删除.meta,Unity可以确保重新天生的GUID和现有的一样。
  • 在Unity关闭的情况下,移动大概删除.meta文件,Unity无法规复到原有的GUID,也就是说引用会丢失。
 
确定了资产文件之后,还须要一个Local IDs来表现当前的Objects在资产里的唯一标识。File GUID确保了资产在整个Unity工程里唯一,Local ID确保Objects在资产里唯一,如许就可以通过二者的组合去快速找到对应的引用。
Unity还在内部维护了一张资产GUID和路径的映射表,每当有新的资源进入工程,大概删除了某些资源,又大概调整了资源路径,Unity的编辑器都会主动修改这张映射表以便精确地记录资产位置。所以如果.meta文件丢失大概重新天生了不一样的GUID,Unity就会丢失引用,在工程内的表现就是某个脚本显示“Missing”,大概某些贴图材质的丢失导致场景出现粉赤色。
 3、Library中的资源位置
前面我们提到了非Unity支持的格式,须要由导入器举行资源转换。之所以要分到这个末节来讲位置是由于它涉及到了File GUID。之所以须要对资源转换和存储,也是为了方便下一次启动的时候不须要再处置惩罚资源,比较每次导入资源是巨耗时的利用。简朴来讲,所有的转换结果都会存储在Library/metadata/目次下,以File GUID的前两位举行命名的文件夹里。
4、Instance ID
File GUID和Local ID确实已经可以或许在编辑器模式下资助Unity完成它的规划了,与平台无关、快速定位和维护资源位置以及引用关系。但若投入到运行时,则另有比较大的性能问题。也就是说运行时照旧须要一个表现更好的体系。于是Unity又弄了一套缓存(还记得前面那套缓存嘛?是用来记录GUID和文件的路径关系的)。PersistentManager用来把File GUIDs和Local IDs转化为一个简朴的、Session唯一的整数,这些整数就是Instance ID。Instance ID很简朴,就是一个递增的整数,每当有新对象须要在缓存里注册的时候,简朴的递增就行。有关PersistentManager的详细分析,我找到了一篇UWA学堂的文章,各人可以在这里详细相识: 《深度分析PersistentManager.Remapper内存占用》
简朴来说:PersistentManager会维护Instance ID和File GUID、Local ID的映射关系,定位Object源数据的位置以及维护内存中(如果有)Object的实例。只要体系剖析到一个Instance ID,就能快速找到代表这个Instance ID的已加载的对象。如果Object没有被加载,File GUID和Local ID也可以快速地定位到指定的Asset资源从而即时举行资源加载。原来这章节的内容我是计划团体配图讲解的,但我发现两篇已经完稿而且配图的大佬文章,所以就不重复造车了,直接给出链接:
一篇是UWA Blog的文章:《Unity文件、文件引用、Meta详解》
别的一篇是来自腾讯GAD的:《程序丨入门必看:Unity资源加载及管理》
 
三、资源生命周期

到现在为止我们已经搞清楚了Unity的Asset在编辑器和运行时的关联和引用关系。那么接下来我们还要关注一下这些资源的生命周期,以及在内存中的管理方式,以便各人能更好地管理加载时长和内存占用。
1、Object加载
当Unity的应用程序启动的时候,PersistentManager的缓存体系会对项目立刻要用到的数据(比如:启动场景里的这些大概它的依靠项),以及所有包罗在Resources目次的Objects举行初始化。如果在运行时导入了Asset大概从AssetBundles(比如:长途下载下来的)加载Object都会产生新的Instance ID。
别的Object在满意下列条件的情况时会主动加载,比如:


  • 某个Object的Instance ID被间接引用了
  • Object当前没有被加载进内存
  • 可以定位到Object的源位置(File GUID 和 Local ID)
别的,如果File GUID和Local ID没有Instance ID,大概有Instance ID,但是对应的Objects已经被卸载了,而且这个Instance ID引用了无效的File GUID和Local ID,那么这个Objects的引用会被保留,但是现实Objects不会被加载。在Unity的编辑器里会显示为:“(Missing)”引用,而在运行时根据Objects范例不一样,有大概会是空指针,有大概会丢失网格大概纹理贴图导致场景大概物体显示粉赤色。
2、Object卸载
除了加载之外,Objects会在一些特定情况下被卸载。
(1)当没有使用的Asset在实行清算的时候,会主动卸载对应的Object。一样平常是由切场景大概手动调用了Resources.UnloadUnusedAssets的API的时候触发的。但是这个过程只会卸载那些没有任何引用的Objects。
(2)从Resources目次下加载的Objects可以通过调用Resources.UnloadAsset API举行显式的卸载。但这些Objects的Instance ID会保持有效,而且仍然会包罗有效的File GUID 和LocalID。当任何Mono的变量大概其它Objects持有了被Resources.UnloadAsset卸载的Objects的引用之后,这个Object在被直接大概间接引用之后会立刻被加载。
(3)从AssetBundles里得到的Objects在实行了AssetBundle.Unload(true) API之后,会立刻主动的被卸载,而且这会立刻让这些Objects的File GUID、Local ID以及Instance ID立马失效。任何试图访问它的利用都会触发一个NullReferenceException。但如果调用的是AssetBundle.Unload(false)API,那么生命周期内的Objects不会随着AssetBundle一起被烧毁,但是Unity会停止File GUID 、Local ID和对应Object的Instance IDs之间的接洽,也就是说,如果这些Objects在将来的某些时候被烧毁了,那么当再次对这些Objects举行引用的时候,是没法再主动举行重加载的。
别的,如果Objects停止了它和源AssetBundle的接洽之后,那么再次加载相同Asset,Unity也不会复用先前加载的Objects,而是会重新创建Instance ID,也就是说内存里会有多份冗余的资源。
Addressable底子篇系列干系课程:
第二节:《Resources目次的长处与痛点》
第三节和第四节:《AssetBundle的原理及最佳实践》
第五节至第九节:《Addressable Assets System》
第十节:《资产导入新管线:加速资源导入的坚固底子》
第十一节:《使用Unity Accelerator加速你的团队》
封面图泉源:Substance Painter To Unity
从Allegorithmic的Substance Painter转向Unity的过程。
Substance Painter To Unity -- UWA问答 | 开源库 | 资助开辟者发现更好的办理方案| 侑虎科技


来源:https://blog.csdn.net/zaizai1007/article/details/130048348
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则