Addressable RemoteBuildPath下部分资源更新上传问题

Addressable RemoteBuildPath下部分资源更新上传问题

1)Addressable RemoteBuildPath下部分资源更新上传问题
​2)Shader内存占用突然变大
3)Unity 2018.4上材质对贴图的冗余引用
4)编辑器中出现大量GC操作导致卡顿
5)JsonUtility.ToJson浮点型保留小数问题


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

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

Addressable

Q:Addressable设置好RemoteBuildPath路径后,Remote_Group(该Group下有多个资源包)下修改了一个资源包,Build->Update a previous build 结束后,RemoteBuildPath路径下将Remote_Group的所有资源包都重新生成了一遍(将所有的资源包从该路径下删除,再执行时还是会全部生成)。因为要将Remote_Group下的资源包上传到服务器,只希望上传发生改变的Remote资源,不希望重复上传所有的资源包,该怎么操作呢?

A:虽然全部重新生成,但是应该只有修改了的那份是不一样的,可以对比一下看看hash文件里记录的hash有没有变化。其实在服务器上直接都上传就行了,客户端会根据hash的不同下载变化了的Bundle。这种模式能保证服务器上的是最新的,客户端不管哪个版本都只要下载差异Bundle就行了。

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

A2:用了一个折中的办法,每次上传前计算已存在文件的md5,新的文件和md5值发生变化的文件上传至服务器。

感谢题主猴小样2016@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/609b48a56bb31032f9791672


Memory

Q:项目Unity版本升级后,Shader内存占用变为原先的100倍,请问是什么原因导致的?

A:这个应该是因为Unity 2019.4.20这个版本以后修改了Shader内存占用的统计方式。Unity这样改,方便大家直接看到是哪个Shader占用高,从而更好地定位问题。

可以看到在版本升级后,Shader占用120多MB,ShaderLab变成了92KB。


2019.4.20f1 Release Notes

感谢芭妮妮@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/60a367746bb31032f979173b


Material

Q:打包后使用AssetHunter插件分析发现有很多冗余引用,但是在游戏中使用Profiler却没有。

打开材质文件发现保存了很多旧的贴图引用信息:

如_CloudTex这个,是旧版本使用过的,新的Shader里都没有这个属性了。一般的查找引用的方法是找到所有关联的GUID,那就会找到这些旧的引用,但在手机上使用Profiler看内存时却没有相关引用的贴图被加载。是否是因为Unity打包时会自动把这些旧引用筛除?尽管在Editor上还是找得到这些冗余引用,是否可以不用理会?

A1:旧的Shader使用过的Texture引用会被保留在序列化信息中,这是Unity有意的设计,为了避免编辑器下切换Shader再换回来时需要重新配置的麻烦。

Unity在打包时确实会对材质进行深度检查,把当前Shader没有使用的Texture依赖都去除,因此通常情况下打包旧的引用也不会导致包体变大。

但旧的引用在Editor下还存在一个问题,AssetDatabase.GetDependencies接口返回的引用会包括旧的引用,它不会进行深度检测来进行剔除。右键资源Select Dependencies调用的是这个接口,所以也会显示旧的引用,如下图:

pic2和pic3是当前Shader2没有引用的。

所以使用GetDependencies这个接口实现一些功能,可能由于旧引用导致意外的问题。解决方法是:使用EditorUtility.CollectDependencies这个接口返回剔除旧引用的结果。

此外,如果Mat和pic1,pic2,pic3分配别单独打了一个AB包,那么打出的mat.manifest文件中会显示旧的Texture引用,这就是AssetBundle打包的一个不太合理的地方了,还没有调研新的Addressable系统是否做了改进。

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

A2:参考这个帖子:
https://forum.unity.com/threads/material-asset-keeps-references-to-assets-that-are-not-used.523192/

可以直接用里面的CleanUpMaterials来清理材质。

感谢小埃拉@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/60a65af06bb31032f9791779


Editor

Q:编辑器下AssetDatabase.GetAllAssetBundleNamesWithoutVariant()出现大量GC操作导致卡顿。

复现步骤:
1.游戏里面选择一个材质,或者其他对象。
2.把Unity编辑器切换到后台再切回来,我这里是直接点开Sublime再切回Unity
做完上面两步后,Unity就会变的很卡很卡,通过Profiler分析EditorLoop可以看到AssetDatabase.GetAllAssetBundleNamesWithoutVariant有大量的GC操作,如下图:

用的是Unity 2019.4.15f1,下面是我尝试过的解决方案:
1.怀疑Unity版本问题,可是笔记本里面安装的同版本Unity新建工程是复现不了。
2.怀疑OnInspectorGUI有问题,然后把代码里面的所有OnInspectorGUI注释了,也还是能复现。
3.怀疑ShaderGUI有问题,把所有ShaderGUI相关代码删了,一样能复现。

有大佬可以提供其他思路去排查这个问题吗?我们现在临时解决方法是,切换一下选中对象就不卡了。

A:项目中是通过设置AssetImporter的bundleName来标记Bundle的吗?

importer.assetBundleName = bundleName;
importer.assetBundleVariant = variant;

查看了一下编辑器部分的源码,发现AssetDatabase.GetAllAssetBundleNamesWithoutVariant();这个API是在绘制下面这部分的时候调用的。

猜测如果BundleName和BundleVariant较多,会不会引起卡顿?

Q:我们项目导入资源的时候是有只设置了Bundle Name,也就是下面的设置方式 importer.assetBundleName = bundleName; 项目是没有设置BundleVariant,不过确实有不少BundleName,对于BundleName数量官方有上限要求?

A:你可以试一下在代码中手动调用一下AssetDatabase.GetAllAssetBundleNamesWithoutVariant()(internal方法,通过反射调用),看看是不是会造成大量GC和卡顿。如果自己调用也会造成卡顿,八成就是这个引起的。如果就是这个Bundle Name这个过多因此的卡顿,那你就用AAB的方式打bundle就好了,别设置importer.assetBundleName。

感谢马三小伙儿@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/60a3ab2e6bb31032f9791754


Script

Q:在使用JsonUtility.ToJson时,保存float类型时,提前已经做好保留两位小数,但ToJson结果1.059999999999999都是这样的。请问有解决办法吗?

A:很遗憾,Unity的JsonUtility是在Native层实现的,是闭源的并且提供的接口功能极少。建议使用其他Json插件,如Newtonsoft.json:
https://github.com/SaladLab/Json.Net.Unity3D

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

A2:自荐一下魔改版LitJson4Unity。
https://github.com/XINCGer/LitJson4Unity

LitJson4Unity:适用于Unity的改进型LitJson库
简介:基于原生的LitJson库改造的适用于Unity的LitJson库。
支持以下原生版本不支持的特性:

  • 支持float类型(最新原生版本已经支持)
  • 支持Unity内建类型(Vector2、Vector3、Rect、AnimationCure、Bounds、Color、Color32、Quaternion、RectOffset等)
  • 支持JsonIgnore Attritube,对某些字段跳过序列化
  • 支持对输出的Json内容格式化,更规整
    使用方法:直接将 Plugins/LitJson目录下所有的cs脚本放到你的工程中即可。

【Unity游戏开发】跟着马三一起魔改LitJson
https://www.cnblogs.com/msxh/p/12541159.html

感谢马三小伙儿@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/60a780756bb31032f9791813

封面图来源于网络


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

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