【厚积薄发】Addressable如何删除旧资源

1)Addressable如何删除旧资源
​2)Addressable如何更新Catalog文件
3)Editor在Android平台下加载AssetBundle的疑问
4)资源被打成AssetBundle后,图集被屡次加载在内存中
5)Gfx.WaitForPresent耗时与GPU的关系html


这是第209篇UWA技术知识分享的推送。今天咱们继续为你们精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。缓存

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)安全

Addressable

Q1:目前计划使用Addressable来实现资源热更新,实际真机测试发现当资源更新后,旧的资源Addressable并不会把它删除,同时能够看到App占用的数据文件会愈来愈大。请问有什么办法能够把指定的Group或Label的资源删除吗?网络

试了Addressable.ClearDependencyCacheAsync也不行。实际测试这个接口只能删除最新版本的资源。当本地已是最新版本资源时这个接口确实有效;可是若是本地须要更新资源时,这个接口应该也是尝试去删除最新资源,然而本地并无最新版的资源,因此大概就无效了。多线程

A:调用Addressable.ClearDependencyCacheAsync实质是调用了 “Caching.ClearAllCachedVersions();”。事实上是使用了Unity的Caching系统。

在Windows编辑器环境测试了一下。
Caching的目录为“C:\Users\UserName\AppData\LocalLow\Unity\ProjectFolder”,当正常下载AssetBundle之后,该目录内就出现 “stage01_298bd883434eedb69ea7316cb23e0b0d\662ab7a0d2aa99bc7a2dbb7baec63872” 之类的目录,并保存着当前的AssetBundle版本,当更新AssetBundle并执行下载之后,该目录也会出现其余AssetBundle的Caching目录。编辑器

在执行下载以前,先执行了一下“Caching.ClearCache();”,这时会发现Caching目录内已经被清空,全部版本的AssetBundle都没有了。下载完成后,该目录只保留了最新的AssetBundle资源。由此可推,即便不经过Addressable系统,仍然能够经过Caching把全部的资源都清理掉。ide

因而继续进行第二个实验,连续更新几回AssetBundle之后,Caching目录内已经有多个版本的AssetBundle目录了,当有新的更新后执行 “Addressables.ClearDependencyCacheAsync(key);”,发现的确并无将旧版本的AssetBundle都删除。由于“Caching.ClearAllCachedVersions”的参数是对应的AssetBundle名字,而Addressables的管理AssetBundle包名是带Hash的,由于每一个版本的AssetBundle文件名都不同的,Caching系统也就没法分辨了。工具

继续作实验,将打包名字去掉Hash,Caching目录内的AssetBundle目录名也不带Hash了,而后连续更新几个版本后发现,该AssetBundle目录内多了几个不一样Hash版本的目录,内部才是真正的AssetBundle。因而走“Addressables.ClearDependencyCacheAsync(key)”,这时就能正确地删除旧版本,而后再更新新版本了。post

Q2:确实不勾选Hash打包能够成功删除了,这种方式貌似就是覆盖式的打包,不知道会不会有其余隐患,目前来看够用。测试

A:隐患就是若是按照Label来作更新检查,原本能够只下载差别部分,可是由于一样使用Label作清除Caching的工做就会形成重复下载本来没必要要更新的部分。因而就须要遍历全部的Location而后去检查更新,并将有更新的AssetBundle放入列表,而后再依次清除旧缓存,从新下载。这样就和传统方案没太大区别了。

Q3:请问下不勾选Hash其实就不用清除了吧?名字同样不是会直接覆盖吗?

A:不勾选Hash,只是在Cache的目录内第一级资源同名子目录是一致的,可是里面保存具体数据的子目录是递增的,由于有不一样版本。每一个版本都会有一个子目录。这个是Caching系统管理的。

感谢黄程@UWA问答社区提供了回答


Addressable

Q:项目使用Addressable作资源管理,资源更新方面由于原来有一套下载更新流程,就不使用Remote功能,所有Group都是cannot change post release。只是单纯用Addressable打包,而后比较差别下载回本地,使用“Addressables.InternalIdTransformFunc”指向新资源的路径。

可是因为下载回来新的Bundle的crc跟原始Catalog的crc不一致,会报错“CRC Mismatch. Provided 16302c0b, calculated 17167beb from data. Will not load AssetBundle”。

但愿在下载完资源后从新加载新的Catalog文件,应该怎么实现?尝试使用了“Addressables.LoadContentCatalogAsync”接口加载下载回来的Catalog文件,可是仍是报错。

A:使用“Addressables.LoadContentCatalogAsync”后仍是出错的可能性有一种:由于默认的Catalog对应的Locator并无移除,形成查找时首先在默认的Locator内找到资源,而由于不走Addressable的更新流程,那么默认的Locator对应的crc永远就是旧的,因而出错了。

感谢黄程@UWA问答社区提供了回答


Rendering

Q:Unity Editor下加载AssetBundle,材质球Keywords正常,可是某些属性不存在。
Unity 2018.4.23f1 Android版本,Shader用的是新建的SurfaceShader,Shader Stripping设置以下图。

Mat、Shader、Prefab打在同一个Assetbundle上,在Editor中运行加载该Assetbundle上的Prefab,会发现一些属性不存在,而本来挂在这个场景中的Prefab,则是正常。

A:打包成APK后链接FrameDebugger看到在场景中的球和AssetBundle加载后实例化的球的Shader参数信息彻底是同样的,因此多是在Android平台Build后的AssetBundle在Editor中加载才会出现楼主所说的问题。

另外再作了一个对比试验,将平台切换成PC。在编辑器里,场景中原有的球和AssetBundle加载出来的球的渲染就是彻底同样的了。

感谢Xuan@UWA问答社区提供了回答


AssetBundle

Q:资源被打成AssetBundle之后,发现图集被屡次加载在内存中,这正常吗?

如果不正常,是什么缘由形成这个问题的呢?怎么解决?(Unity版本是2017.3.9)

A1:多是在经过AssetBundle.Unload(false)卸载AssetBundle对象后,从新建立该AssetBundle对象并加载以前加载过的资源到内存,这样就出现了冗余。还有一种就是打包时出现了冗余。

感谢李星@UWA问答社区提供了回答

A2:根据经验说说形成这种状况的缘由。

  1. 确认打包的时候,图集是依赖的打包,而没有被打包到各个prefab里面。这个推荐使用UWA的在线AssetBundle资源检测工具,直接把整个项目的AssetBundle上传,能够查出不少问题。
  2. 你把Assetbundle包给卸载了。AssetBundle.Unload(false),这样Assetbundle关联断了,就会从新加载资源,若是楼主用的是LZ4的压缩格式,不推荐再去调用Unload(false)了,第一LZ4的ab包自己占用极少的内存,第二Unload(false)的资源多了,调用Resources.UnloadUnusedAssets接口,容易形成卡顿。应该本身写引用AssetBundle计数,直接Unload(true)。

感谢简单就好@UWA问答社区提供了回答

A3:根据经验有如下几点供参考。

  1. 使用Unload(true) 更好一些。常常会有人操做不规范挂住一些资源,而后越积累越多,主动释放安全不少。
  2. Unload(false) 会致使再次加载同一资源被开一个新的区域。某些重复利用率较高的资源,会出问题。好比,材质A和材质B都引用一个贴图,加载材质A根据依赖加载贴图,而后释放AssetBundle;加载材质B时,会加载第二份贴图。因此用Unload(false) 并不能达到及时释放ab的效果。
  3. 反复加载的问题。卸载AssetBundle以后,再次使用还没有析构的资源,又须要从新加载AssetBundle,虽然LZ4的加载速度能够忽略不计。

感谢欧月松@UWA问答社区提供了回答


Rendering

Q:请教一下,在报告中看到Gfx.WaitForPresent很高,是否是就说明GPU压力很大?CPU均值在19ms左右,是否是说明压力在GPU端而不是CPU?是否应该先去优化GPU?

A1:Gfx.WaitForPresent的值高通常是开了多线程渲染,要么在作垂直同步,要么GPU负担较重,CPU已经作完了等着GPU完成作呈现。建议查一下具体渲染的内容,或者在Profile内看看渲染线程的工做状况。

参考文章:《扒一扒Profiler中这几个“占坑鬼”》

感谢黄程@UWA问答社区提供了回答

A2:Gfx.WaitForPresent就是GPU瓶颈:

  1. 降分辨率;
  2. Shader优化,优化指令,高中低配使用不一样的Shader LOD;
  3. 作视距控制,不光减DrawCall,不透明物体一样存在Overdraw,特别是场景复杂度高的状况下。

感谢BQ哥@UWA问答社区提供了回答

封面图来源于网络


今天的分享就到这里。固然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,咱们早已在UWA问答网站上准备了更多的技术话题等你一块儿来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com 官方技术QQ群:793972859(原群已满员)

相关文章
相关标签/搜索