AssetBundle如何计算可靠的Hash值

AssetBundle如何计算可靠的Hash值

1)AssetBundle如何计算可靠的Hash值
2)升级后的物理开销问题
3)UWA GOT支持iOS后无法出包问题
4)如何释放Live2D new的Mesh
5)雾效Fog在手机上失效的问题


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

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


AssetBundle

Q:项目之前是使用建置出来的AssetBundle档案,自己算MD5当作用户端更新比对项目。但因为AssetBundle建置的不稳定性,常常Asset没有改变但是AssetBundle变了,导致用户端下载到不必要的AssetBundle。所以后来开始试着从Asset算一个Version Hash值。目前引入的参数有:

  • AssetBundleName
  • 有依赖但不在这个AssetBundleName下的Asset的路径与其 AssetBundleName
    (跨AssetBundle引用实验出来是看AssetBundleName,当有依赖的Asset AssetBundleName改变则必须替换AssetBundle否则依赖加载会失效)
  • 所有这个AssetBundleName下Asset档案的MD5
  • 所有这个AssetBundleName下Asset档案的.meta的MD5
  • 所有跟这个AssetBundleName下的Sprite共用同一个Atlas,但不在这个AssetBundle的Sprite Asset与其.meta的MD5

但是这个方案实际应用还是有很多问题:

  • Version Hash计算很久(有想过直接重复利用Unity AssetDatabase里的 Hash128,但是貌似很多人都遇到Hash128也不稳定的问题)
  • AssetBundleName如果在建置时修改则不一定会写到.meta,造成.meta的档案MD5是错的。除非Reimport,但是Reimport就会造成建置时间暴涨(如果是把 AssetBundleName commit进Repo建置时不设定,则有可能有忘记commit的问题)
  • ScriptableObject .asset没有commit却在Build machine自行变化,有的时候是 SerializeFile触发升级Migration(但是升级时间点非常谜,有时候本地用相同版本Reimport All也不升级,在Build machine却又有升级),有的时候是清单项目顺序调换

感觉自己Version Hash好像也没有完全解决问题又造成建置时间增加,所以想问在运营大项目的大佬们有什么建议,谢谢。

A1:个人还是投票给构建完毕之后的AssetBundle的Hash值。

一方面担心自己构建的不能覆盖所有更改的情况(题主考虑的已经挺全面),另外一方面是.meta文件本身就不是为构建唯一性设计的,比如它混合了各个平台的参数,任何一个平台的参数修改都会导致其内容的更改,因此我们必须参考meta,而它的修改又不一定意味着资源的修改,这样就很尴尬。

在这个前提下,可以做的事情是尽量发现和解决资源相同但是AssetBundle的文件Hash值却不同的情况。
感谢贾伟昊@UWA问答社区提供了回答

A2:我们是这样做的:
AssetBundleHash结合AssetFileHash,在Bundle对应的manifest文件中可以取到AssetFileHash值。

ManifestFileVersion: 0
CRC: 3889896754
Hashes:
  AssetFileHash:
    serializedVersion: 2
    Hash: 7a90127ef724ff63cb40874dc69929b8
  TypeTreeHash:
    serializedVersion: 2
    Hash: 0d46a8251e1e96cd839078edaf4c28a3

对于AssetBundleHash不同但AssetFileHash相同的,按未变化处理。

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


Physics

Q:一个项目场景里只有静态碰撞盒, 用于玩家点击选中。Unity 5.6之前,物理开销基本没有。 升级到Unity 2018后,分析报告里的物理开销2ms不到,虽然不多,但是很奇怪。

后来发现Project Settings里把Physics.autoSimulation关了之后开销就下去很多了, Physics2D.autoSimulation关了之后会再下去了一点点。这个参数好像是Unity 2017之后新加的参数。

看介绍,关了这个参数之后每次LateUpdate的时间里就不会自动处理物理方面的计算, 可以手动调用Physics.Simulate来手动控制物理计算。

A:物理系统不会自己去运行了。在5.4~2017.2版本中,Unity引擎可以根据你们项目中Rigidbody的使用情况来自己决定是否开启物理引擎,如果没有使用,则它会自动关闭。但是,在2017.4版本以后,物理引擎会自动开启,Unity引擎推出API由开发团队自己去控制是否开启和关闭。所以,一般在最新的版本中,UWA都建议大家看看你们的物理模块开销,是否在自动空转,如果耗时较高,则可以尝试自己去关闭Auto Simulation选项。

但是,需要说明的是,如果场景中含有Trigger、布料模拟等,则关闭Auto Simulation后则不起作用了,这个时候研发团队需要根据自身情况来决定该选项的开启和关闭。

该回答由UWA提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5dc9229f7307ec2f0f99a1bd


SDK

Q:最近有看到UWA GOT工具新增了iOS版本的支持,于是下载了最新的工具包进行了接入测试。是按照文档直接将UWA_GOTv2.0.1_iOS.unitypackage导入进了Unity项目内,并且做了配置。

但是发现添加了UWA GOT插件以后iOS上不能正常出包,总是卡在xcodebuild archive这一步,报错信息如下:

** ARCHIVE FAILED **


The following build commands failed:
  Check dependencies

我们打的是Distribution包,是否跟这个有关系?已经确认就是添加了UWA_GOT插件以后引起无法打包的问题,因为在移除了SDK以后可以顺利出包了,麻烦各位前辈帮忙解答下。
(版本:Unity 2018.3.4f1)

A:目前已经解决,是被上面的报错信息混淆了视听。

之前因为打包环境比较复杂,有的时候不能得到真正的报错位置,而且同时还要不停地有出包任务,不好做调试。所以今天单独在一台纯净的Mac上面模拟了打包环境,并接入UWA GOT的iOS版SDK,测试了以后有以下发现:
1、导出xcode工程并且在xcode中直接build不会报错。
2、导出xode工程,然后在xcode中执行Build Archive会报错。

报错信息类似于下面这样:

ld: bitcode bundle could not be generated because
 '/xx/libuwa.a' was built without full bitcode. All object files and libraries for bitcode must be generated from Xcode Archive or Install build for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这样就比较好解决了,原因是如果一个工程里面有静态库的引用,那么所有的静态库也需要打开Bitcode后重新编译。这一切在直接Build的时候都没有问题,但是在“Archive”的时候就会报错。

我们在出iOS包的流程是先Build Archive然后在export Archive导出ipa,因此就会出现问题了。

解决方法比较简单,我是直接在执行xcodebuild命令的时候把EnableBitcode设置为NO了,类似于下面的命令:

xcodebuild -target <your target> -configuration <your configuration> **ENABLE_BITCODE=NO**

看网上还有一种解决办法是不关闭bitcode,然后在执行xcode build命令的时候带上参数。

OTHER_CFLAGS="-fembed-bitcode"

后面这种没有试过不知是否奏效,希望可以帮助到大家。

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


Loading

Q:项目用的Live2D,创建后其框架会动态new大量Mesh,想求教下除了用Resources.UnloadUnusedAssets()接口外,有没有方法能指定只释放这部分Mesh?

A:Live2D有两个大坑:
(1)CubismRenderer初始化new Mesh[2],并没有销毁代码

代码修改如下:

(2)MeshRenderer.material实例化独立材质

代码修改如下,运行时还需要把所有MeshRender的材质设置成同一个材质:

感谢晨星@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5dccdbff14ec712eefaf01a6


Rendering

Q:在PC上面,整个场景中有雾效,单独对这个场景打包AssetBundle,那么在手机上面没有雾效。如果是直接将该场景丢在Hierarchy上build,在手机上面可以看见雾效。请教下,这个是哪里出了问题?都是在同样的手机上面测试的。

A:可能是graphics里的雾选项没勾Shader裁剪了。

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

封面图来源:Animation Rigging: Advanced Setups
展示了Unity动画索具包的高级设置和用例。
https://lab.uwa4d.com/lab/5d3cbe3e5b9dec79de32a9e8


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

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