失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Shader打AssetBundle包变体丢失问题

Shader打AssetBundle包变体丢失问题

时间:2023-09-22 02:01:01

相关推荐

Shader打AssetBundle包变体丢失问题

1)Shader打AssetBundle包变体丢失问题

​2)Unity升级后在iOS平台的贴图导入问题

3)字体文件AssetBundle包崩溃

4)给主相机设置RT的注意事项

5)FBX的导入WeldVertices的设置问题

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

UWA 问答社区:

UWA QQ群2:793972859(原群已满员)

AssetBundle

Q:Unity官方后处理PostProcessing,进行AssetBundle打包时,变体太多(4000+),修改了uber.shader,屏蔽了项目中不可能使用的关键字(后期要使用也可以通过热更修改)。

AssetBundle打包后,发现变体没完全打包,Editor下查看Shader变体数量是300+,打包后使用AssetStudio查看AssetBundle,发现只打了100+的变体,大部分丢失。运行通过断点调试也验证了所有Key均设置,FrameDebug中也丢失了一些关键字。

uber.shader下所有关键字均是multi_compile 定义,理论上multi_compile定义的关键字都会全编译所有组合,但是打包后出现丢失。

A:在进行单元测试中,在一个空项目中打包uber.shader,发现打包后,变体正确。但是开发项目和打包项目依旧生成不正确。怀疑是Unity缓存原因。于是删除Library目录下shaderCache,再次打包,还是不正确。再次删除已生成的AssetBundle资源,完全重新生成,终于正确。

所以multi_compile定义的关键字打包出现问题,需要删除缓存和已生成的AssetBundle才能最终正确生成新的AssetBundle。

感谢题主1 9 7 3-311135@UWA问答社区提供了回答,欢迎大家转至社区交流:

AB打包参数DisableWriteTypeTree导致编辑器下AssetBundle.LoadAsset()方法调用TMPTextPro的字体文件AB包崩溃 -- UWA问答:帮助开发者找到更好的答案

Asset

Q:我们一直用贴图后处理脚本对贴图进行导入,在iOS平台使用ASTC_6x6格式。但是升级到Unity ,打开iOS工程,经同步缓存和导入完成后,大部分贴图的预览界面上并没有显示压缩格式和压缩后的尺寸,而是显示no yet compressed,似乎导入操作没有完成。Android平台并没出问题。

这样的贴图会显示模糊,并且打出的Bundle还会更大。手动Reimport可以解决。但是如果另外建立一份工程拷贝,则又会出现同样的问题。求问有什么解决方法?

A1:经查,是我这边的纹理资源导入后处理脚本(iOS)有问题,但是其在Unity 下不会体现出来,但是在Unity 中会直接让某些贴图的导入工作无法完成。由于使用了 Unity Accelerator(也就是Asset Pipeline v2对应的缓存服务器),重新导入也不会生成新的缓存,只能让进行重新导入的项目局部正常。

我们的导入后处理脚本中在iOS下,对JPG单独使用了不带透明通道的ATSC压缩。在Unity 中,ATSC压缩不再区分是否带透明通道。修改脚本+删除Unity Accelerator缓存+重新导入某个Working copy(同时也重建了缓存)可解决。

注意:上述无法导入完成的情况,打出包来会有两个明显的问题:包体变大、图片模糊。

感谢题主加菲教主@UWA问答社区提供了回答,欢迎大家转至社区交流:

AB打包参数DisableWriteTypeTree导致编辑器下AssetBundle.LoadAsset()方法调用TMPTextPro的字体文件AB包崩溃 -- UWA问答:帮助开发者找到更好的答案

AssetBundle

Q:AssetBundle打包参数BuildAssetBundleOptions.DisableWriteTypeTree。会极大缩减AssetBundle包大小,同时也带来运行时SerializaFile相同数量级下内存占用缩减一半左右,并提高加载速度。

官方说明比较简单:如果开启DisableWriteTypeTree选项,则可能造成AssetBundle对Unity版本的兼容问题。基于其带来的运行时优势,还是决定使用该选项。

导出测试包一切运行正常,热更新也运行正常,本来以为该优化就完结。但是后来发现相同的AssetBundle资源,在编辑器下AssetBundle运行会崩溃(必然出现),导出的测试包(所有平台)一切正常。(该问题必须要解决,因为游戏发布后线上的问题可以在本地调试复现,如果本地不能运行AssetBundle包或者运行不同的AssetBundle包原则上不允许。)

A:开始排查问题:首先定位到崩溃的资源,是TMPTextPro相关的字体资源包(复合包,包含了多个资源内容)。

验证BuildAssetBundleOptions.DisableWriteTypeTree的影响,屏蔽BuildAssetBundleOptions.DisableWriteTypeTree打包参数。打包后编辑器运行不崩溃,肯定了该参数造成的问题。(这里当时猜测是Unity内部代码的某个宏导致的,导致了在Editor下和发布时走了不同的解析代码,但是又没有源代码,无法具体验证。)

开始排除问题:

首先排除Unity的编辑器缓存造成的该问题,重置后依旧崩溃。

开始拆解问题包,将所有资源内容单个打包(一个资源对应一个包)。最后精确定位到是TMPTextPro的字体FontAsset资源包调用AssetBundle.LoadAsset()方法时崩溃。

分析问题:设置DisableWriteTypeTree参数将不在AssetBundle中包含相关的文件TypeTree信息,是因为没有该信息后导致的反序列化不正确,为什么其它资源能正常解析,就单单FontAsset会出现问题?打开TMP_FontAsset.cs源码,查看发现这么一段代码。

#if UNITY_EDITOR////// Persistent reference to the source font file maintained in the editor.///[SerializeField]internal Font m_SourceFontFile_EditorRef;#endif

发现它居然在可序列化类中加入了条件编译,造成导出运行和编辑器运行该类的实现不一样。

这就是为什么导出包运行正确,编辑器崩溃的原因。因为AssetBundle打包时的UNITY_EDITOR是不成立的,会设置对应平台的宏。所以打包时FontAsset资源的数据是不包含m_SourceFontFile_EditorRef该属性的序列化信息,未开启DisableWriteTypeTree时,因为有TypeTree信息,编辑下运行程序能通过TypeTree信息正确反序列化,当设置DisableWriteTypeTree时,反序列化失败,直接崩溃。

解决:给属性m_SourceFontFile_EditorRef添加标签[NonSerialized],再对应修改一些Editor代码,让功能在Editor下也正确。

感谢题主1 9 7 3-311135@UWA问答社区提供了回答,欢迎大家转至社区交流:

AB打包参数DisableWriteTypeTree导致编辑器下AssetBundle.LoadAsset()方法调用TMPTextPro的字体文件AB包崩溃 -- UWA问答:帮助开发者找到更好的答案

Rendering

Q:用setTargetBuffers方法将一张低分辨率RT设置给主相机。在屏幕分辨率不变的情况下,对场景相机做了降级。然后出现了一个问题是:所有的后处理都失效了,查看后发现所有OnRenderImage方法的Source都为null(我理解为没有设置Rendertarget,默认为屏幕)。我将上面那张FrameBuffer强行代替Source传入后处理,查看FramedeBugger,后处理几个Draw Call能正常渲染,但是仍旧不能对最终效果生效,也就说没有写入到上面的FrameBuffer。

我之前的解决方法是魔改所有OnRenderImage,传入FrameBuffer代替Source,输出到另外一张FinalBuffer,最后再绑定到屏幕上,下面是测试代码。

但项目中后处理比较多,且ImageBuffer仍存在后处理中,无端增加了RenderTexture的开销。

现在的处理方法是直接设置TargetTexture,但逻辑操作上会绕一层。想问下引起上面的原因,或者说有什么更好的解决方法?

环境是.4.3f + built-in + OpengES3.0,然后再用CommandBuffer将低分辨率适配到高分辨率。

A1:实践下来,建议还是用CommandBuffer来操作,比较灵活:

OnPreRender阶段先设置好TargetBuffer(ColorBuffer:RTA、DepthBuffer:RTB)。使用CommandBuffer在CameraEvent.BeforeImageEffects或者AfterImageEffects这个事件上做所有的后处理。核心在于第一次Blit的Source为ColorBuffer,最后一次Blit的Destination为BuiltinRenderTextureType.CameraTarget,中间可以穿插任何后处理效果。

而且如果发现改了ColorBuffer的分辨率,画面没有正常缩放,需要第二步后处理的CameraEvent改为AfterEverything:

还有就是如果改了TargetBuffer,需要对SceneCamera做特殊处理。

感谢范世青@UWA问答社区提供了回答

A2:下图是这两种方法的实验对比,至于两者区别的根本原因,是其方法内部实现的差异:SetTargetBuffers的实现过程是没有设置渲染目标(也就是屏幕)的RenderTexture的,这也就是为何用该方法时OnRenderImage中的Source是null。

该问答由UWA提供,欢迎大家转至社区交流:

AB打包参数DisableWriteTypeTree导致编辑器下AssetBundle.LoadAsset()方法调用TMPTextPro的字体文件AB包崩溃 -- UWA问答:帮助开发者找到更好的答案

Asset

Q:问下在FBX的导入设置里面,weldVertices是需要设置为True还是False?

A:建议设置为True。相同顶点会被合并,可以减少内存和Mesh渲染的压力。

感谢萧小俊@UWA问答社区提供了回答,欢迎大家转至社区交流:

AB打包参数DisableWriteTypeTree导致编辑器下AssetBundle.LoadAsset()方法调用TMPTextPro的字体文件AB包崩溃 -- UWA问答:帮助开发者找到更好的答案

1018

更多精彩问题等你回答~

Unity增量打包AssetBundle没变化的资源也会被重新打包在模型有UV2的情况下开启Generate Lightmap UVs如何实现AAB包的增量更新

封面图来源于网络

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

官网:

官方技术博客:

官方问答社区:

UWA学堂:

官方技术QQ群:793972859(原群已满员)

如果觉得《Shader打AssetBundle包变体丢失问题》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。