Assets--unity资源映射

这篇具有很好参考价值的文章主要介绍了Assets--unity资源映射。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考文章:

浅谈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://www.toymoban.com/news/detail-422768.html

到了这里,关于Assets--unity资源映射的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity中读取Json文件:基于Assets/Resources文件夹

    我好生气😤,Python,JS里面一两行代码能够搞定的Json读取,在Unity中使用C#读取Json文件超多坑,爬出来一个又来一个。 主要是JsonUtility.FromJson太不给力了。 最好的方式是,使用 https://github.com/jilleJr/Newtonsoft.Json-for-Unity 这个第三方库。详情见下。 Step 1: 先把对应的Json File放到

    2024年02月12日
    浏览(40)
  • Mongodb SQL 到聚合映射快速参考

    聚合管道允许MongoDB 提供原生聚合功能,对应于 SQL 中许多常见的数据聚合操作。比如:GROUP BY、COUNT()、UNION ALL For MySQL For Mongodb : 按客户分组,统计每个客户订单数量,并计算订单总价格,按价格从高到低排序。 可以使用聚合管道的方式,如下: $group 按指定的标识符表达式对

    2024年02月15日
    浏览(16)
  • Unity工程目录下的文件夹(Assets、Library、Logs、Packages、ProjectSettings、UserSettings)

    通常Unity里的工程目录都是这样: 一、Assets  工程资源文件夹(美术资源,脚本等等)         Unity工程中所用到的所有Asset资源都放到这个文件夹里,是资源文件的要目录,很多API都是基于这个文件目录。查找目录都需要带上Assets,例如AssetDataBase 二、Library    库文件夹

    2023年04月09日
    浏览(42)
  • 初识Unity——unity的安装以及工程介绍(安装unity hub、版本选择、中文设置、安装编辑器、Assets文件、Library 文件、[ProjectName].sln 文件)

    目录 unity的安装 安装unity hub 版本选择 中文设置 安装编辑器 模块一 模块二 模块三 工程文件介绍 主要文件 Assets Library  其他文件 ProjectSettings Packages [ProjectName].sln  unity国内的官网:https://unity.cn/ 进入国内的官网点击“下载 unity” 下载 unity hub 再进入其中安装编辑器只有相对

    2024年02月05日
    浏览(46)
  • Spring Boot静态资源映射

    在 Web 应用中会涉及到大量的静态资源,例如 JS、CSS 和 HTML 等。我们知道,Spring MVC 导入静态资源文件时,需要配置静态资源的映射;但在 SpringBoot 中则不再需要进行此项配置,因为 SpringBoot 已经默认完成了这一工作。 Spring Boot 默认为我们提供了 3 种静态资源映射规则: We

    2023年04月24日
    浏览(26)
  • 浅谈和辨析数据资源、数据资产、数据要素的区别

    从商业决策到科学研究,从个性化服务到社会治理,数据都在发挥着越来越重要的作用。然而,对于数据资源、数据资产和数据要素这三个概念,人们往往容易混淆。为了更好地理解和利用数据,有必要对这三个概念进行深入的辨析。下面亿信华辰将逐一探讨这三个概念的定

    2024年02月01日
    浏览(42)
  • Springboot后端通过路径映射获取本机图片资源

    项目场景: 项目中对图片的处理与查看是必不可少的,本文将讲解如何通过项目路径来获取到本机电脑的图片资源 如图所示,在我的本机D盘的图片测试文件夹(文件夹名字不要有中文)下有一些图片, 我们要在浏览器上访问到这些图片,很简单,只需要在浏览器导航栏中填写

    2024年02月14日
    浏览(23)
  • go的iris框架进行本地资源映射到服务端

    我这里使用的是 HandleDir api,有其他的请补充 如上图的目录所示,访问地址是 http://localhost:8088/static/video/gdyg1.mp4 即可 将int类型转换成string

    2024年02月09日
    浏览(28)
  • 【vim 学习系列文章 19 -- 映射快捷键调用两个函数 A 和B】

    请阅读 【嵌入式开发学习必备专栏 之 Vim】 在 Vim 中,如果想通过按下 gcm 来调用两个函数,比如 FunctionA 和 FunctionB ,需要先定义这两个函数,然后创建一个映射。这个映射将会在被触发时依次调用这两个函数。 首先,确保 .vimrc 文件中包含了这两个函数的定义,以及一个用

    2024年04月13日
    浏览(40)
  • 基于Web的考试系统的设计与实现(非常工整规范的参考文章)

    【摘 要】随着现代计算机的应用和互联网络技术的进步和迅猛发展,人们日益地依靠互联网和电脑去做各种工作。于是,以减少教师的压力和工作负荷以及大大提高了工作效率、提高考试质量等方式为主要目标的现代化在线考试系统应运而生。本在线考试系统的主要特点就是它

    2024年02月05日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包