LWRP+UGUI使用方式

LWRP+UGUI使用方式

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

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


本期目录:

  • LWRP+UGUI使用方式
  • Tex2DLod在移动设备的支持情况
  • 如何卸载AssetBundle中加载出来的GameObject
  • 线上包升级Unity版本的问题
  • UGUI关于顶点色与材质色的问题

LWRP

Q:由于LWRP不支持多个相机,那UI怎么办?如果UI不用camera,而是改用Overlay,UI特效穿插怎么解决?

A1:UI可以用camera,只是UI不能用多个camera。我们项目现在也有这个问题,需要把我们原本的UI多Canvas多相机改成单个Canvas。可以考虑改一下LWRP的“Blit”Shader,加入一句“Blend SrcAlpha OneMinusSrcAlpha”。
感谢廖武兴@UWA问答社区提供了回答

A2:需要自行扩展加入相机的,如DepthOnly这样的ClearMode来应对此需求。

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


Rendering

Q:因为一些需求需要在Vertex Shader里面用Tex2Dlod采样,但是看了文档说是Tex2Dlod是S-M-3.0的标准,OpenGL ES2.0只是部分实现了S-M-3.0的标准,所以不清楚在实际的设备上,不支持Tex2Dlod的设备有多少。我们游戏需要发海外,如果不支持的比例很大,我们就需要考虑加入一些fallback的机制了。

参考了以下文档:
https://docs.unity3d.com/Manual/SL-PlatformDifferences.html
https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html

A1:Tex2DLod只在部分扩展OpenGL ES2.0功能的手机上支持,但具体如何在运行时识别,UWA并没有特别研究过。一般保险起见,还是在OpenGL ES3.0以上使用Tex2DLod比较好,避免不必要的麻烦。可以看看其他社区朋友,是否有类似的经验。
该回答由UWA提供

A2:如果不是针对固定平台的开发,用到这种对Feature Level有要求的功能,肯定是要做fallback的,一个Shader里写两个SubShader,第一个是最完整功能的,后面的是用来做降级的;如果运行时第一个不被支持,会一个个尝试后面的。
感谢郑昊@UWA问答社区提供了回答

A3:用glGetIntegerv这个API来判断,代码如下:

int MaxVertexTextureImageUnits;
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &MaxVertexTextureImageUnits);

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


资源管理

Q:Resources.UnloadunsedAssets可以卸载掉从AssetBundle中的LoadAsset()中加载出来的GameObject吗?这个GameObject不是Instantiate出来的,而是直接从AssetBundle中加载出来的。发出这个疑问主要是因为Resources.UnloadAsset去卸载这个GameObject的时候会提示报错:GameObject、Component、AssetBundle不能被Resources.UnloadAsset卸载。

A1:可以的,更准确地说,Resources.UnloadunsedAssets实际上卸载的是LoadAsset出来的Object,在实例化之前,我们一般还是不将其称呼为GameObject。
该回答由UWA提供

A2:不知道您是要问Resources.UnloadUnusedAssets还是Resources.UnloadAsset呢?

Unity引擎卸载资源有以下几种方式:

1、Resources.UnloadAsset 这个方法在API文档中可以看到一句话,“This function can only be called on Assets that are stored on disk”,例如:Texture等。而问题中的Component等是不能被这个接口卸载的。

2、Resources.UnloadUnusedAssets 这个方法是一个异步地调用,引擎会完整地遍历一遍后,卸载掉没有被引用的资源。这个接口耗时非常大,需谨慎使用,否则调用时会造成持续的卡顿。

3、AssetBundle.Unload() 这个接口可以通过传入参数的不同来控制是只卸载Bundle还是同时卸载Bundle和Bundle中加载出来的资源。不同的团队在这个接口上的使用方式有所不同,有的团队使用false,有的团队使用true,具体还需要结合具体项目具体分析。一般使用true比较暴力,必须在上层处理好资源和Bundle的引用计数,否则很可能会出现一个还在使用的资源被强行卸载掉。

4、Object.DestroyImmediately 这个接口也可以去卸载掉一些Texture的资源。

针对问题中提到LoadAsset出来的资源,如果引用计数完善,可以在没有资源被使用的时候通过AssetBundle.Unload(true)来完全卸载掉。如果需要单独卸载,不同类型的资源卸载方式也不同,需要针对性的处理。

UWA问答UWA Blog中有很多关于AssetBundle和资源管理相关的文章,建议都阅读一下。

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


版本管理

Q:假如我有一个线上包,用2018.3.5打包的客户端和AssetBundle包,然后现在出了2018.4.0,我发现2018.4里修了一些崩溃的Bug,希望升级到2018.4,但是线上包并不进行强更(因为会流失),而之后的玩家下载的是新包。

现在的问题是:

1、客户端本身用这个操作没有什么问题,我试了下2018.3.5一样能打开2018.4的AseetBundle包,运行起来也没什么问题。
2、但是2018.4打出来的所有AseetBundle包都变了,主要就是文件头那里有个Unity版本号的地方变成了2018.4,内容实际上没什么变化。这就导致以前下载了2018.3.5的客户端的玩家需要重新下所有AseetBundle包。

我想问问有没有人做过线上包升级Unity版本但是不强更的类似处理?这时候AseetBundle包怎么处理的?

A1:两个问题:
1、没做好很基本的线上底包版本的前后兼容和划分。
2、没做好是否要重新打AssetBundle的校验。

解决方式:
1、对各自版本用各自的Unity版本打各自的AssetBundle包,注意添加版本标识,下载各自的AssetBundle。
2、重打AssetBundle校验,打完之后检测还原不需要更新的AssetBundle。
感谢hy@UWA问答社区提供了回答

A2:1、不要使用文件的MD5码做校验,决定是否下载。
2、使用一个版本列表,记录每个文件打包的版本号,根据版本号来决定是不是要更新。
3、版本更新的问题,使用SVN的记录修改来增量更新。这个与Unity的版本号变化没有关系。

所以,就算Unity版本变了,打出来的AssetBundle变化了,但只要是版本没有变化 ,都可以认为是不需要更新的。如果之前已经上线的,就已经是针对MD5做校验更新的那就没办法了。

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


UI

Q:《关于Unity中的UGUI优化,你可能遇到这些问题》关于这篇文章里面“网格重建”的前两个问题:我有些不解。

修改Image的Color,其实是修改最终UGUI生成的Mesh的顶点色,然后通过模型顶点色影响最终表现,这里说的会导致Canvas的Layout相关的重建,以至于导致Canvas重建,不会新增DrawCall,我可以理解。但是通过修改Image使用的MAT的颜色属性去影响最终表现,却会增加一个DrawCall,这里我不理解。

我理解的是[来源于渲染流程]: 在改变MAT颜色的下一个渲染帧,CPU开始组织相关Mesh数据以及渲染状态数据,然后分批次给GPU通知,先SetPass call,后DrawCall,如果按照这个流程走下去,会发现其实DrawCall也不会增加,只不过在某个DrawCall的时候,其Batch的数据和上一帧有一点儿变化。 所以如何理解这里?

A:如果只是渲染一个Image,那么无论怎么做都是只有一个DrawCall;如果多个Image,这就要考虑到优化了,如果不修改MAT的属性,那么所有的Image都是同样的MAT实例,会合批为同一个DrawCall即可绘制;如果你通过修改其中一个Image使用的MAT的颜色属性,那么必定生成一个新的MAT,不符合合批条件,即会用另外一个DrawCall来绘制该Image,即所谓的产生一个DrawCall。

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

封面图:Texture Panner


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

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com

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