Unity UI 显隐(共存)关系的优化处理方案

Unity UI 显隐(共存)关系的优化处理方案

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

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


本期目录:

  • 有关Unity UI 显隐(共存)关系的优化处理方案
  • UWA GOT Online的Lua分析
  • 场景打Assetbundle导致包量变大
  • 如何隐藏iPhone X底部横条
  • 如何在Native代码中设置SkinnedMeshRenderer的骨骼Transform

UI

Q:有关Unity UI 显隐(共存)关系的优化处理方案,大家一般是怎么处理的呢?
1. 情形描述:
情形1:弹窗A中有一个按钮,点击后可以打开弹窗B,然后关掉弹窗A(或者不关掉);
情形2:弹窗C中有一个按钮,点击后打开了一个全屏面板,隐藏(销毁)掉其他所有UI。

......
2. 问题描述
类似问题会影响到Overdraw的指标,显隐关系做的不好,会导致过量的渲染倍率,也会造成UI显示逻辑不合理,不易管理。

各位前辈都是怎么处理类似问题的呢?

A1:题主你好,这类问题每个项目的具体需求可能会不同,如果策划是逻辑性比较强的,又有负责的UI策划的话,最好是先让策划整理一下需求,程序这边再来制定策略会更合理一些。
这里提到的需求一般涉及到以下几个问题:

一、关闭方式

  1. 无限回退,就是说ABC三个界面,可以循环打开,那么在循环打开很多遍以后,通过后退按钮,也会按照打开的顺序后退这么多遍,才能回到主界面。(依稀记得崩3就是这种)
  2. 关闭界面,和第一种不同,就算ABC多次循环打开,也只要关闭一次这个界面就会被关闭了。

二、打开方式
从A打开B,A要不要关闭,即关闭B之后是回到A还是回到主界面。
这里也涉及到AB都为全屏、AB都为弹窗、AB中一个是全屏一个是弹窗的情况。

三、特效、3D模型的层级问题
2D+3D的显示情况,多个UI可能会有穿插问题,这里也要一并考虑进去。

四、关卡结束的显示UI
需不需要在出关卡后显示进关卡之前的状态。

五、公共导航
是所有UI共用一个导航还是每个界面单独做。

常见的就是以上几个吧,需求搞清楚之后再看怎么管理的问题了。

我们项目的做法是管理栈,且大部分是全屏UI,这是前提。所有的UI一个栈,全屏的UI一个栈,全屏UI里只显示最上层的一个。因为我们项目中很少有弹窗UI在全屏UI下面的,这是和策划达成共识的,所以这部分个别情况的Overdraw就忍了。

卸载是通过配置控制的,如果一个系统有多个界面,会在这个系统的入口界面即系统主界面关闭的时候,卸载这个系统的所有UI,因为一般一个系统会有一些共有图集,所以逻辑上也比较合理。当然也看具体是什么系统,重不重要。像一些活动登录运营活动的界面,就即关即卸了。

补充一下使用SetActive方式来隐藏/显示被遮挡UI的几个注意事项:

  1. 不要在OnEnable/OnDisable里写重要逻辑;
  2. Update里写的逻辑注意一下;
  3. 遇到过NGUI的Button状态异常的情况;

感谢小鹿乱撞@UWA问答社区提供了回答

A2:我们是把全屏页面(以下称全屏)和窗口页面(以下称窗口)做了区分。有个大前提,全屏和窗口都独占UI。打开后,无法点击下面。同一时刻只会有一个全屏显示;同一时刻窗口也不会叠加很多。当打开全屏的时候,会关闭上一个全屏页面;当打开窗口的时候,窗口会依赖在当前的全屏上。窗口是全屏的SubItem,无论从哪里打开的窗口,都会创建到全屏的节点下(全屏节点结构统一)。当关闭当前全屏时,释放掉依赖他的所有窗口。当关闭窗口时,只释放自己,同时解除掉全屏上的引用。

程序中有一个栈,用来记录全屏的打开顺序,每打开一个全屏,往栈里压一个type,正常回退的时候按栈里的顺序回退,也可以都回退到目标全屏,就是从栈里往外弹,弹到目标类型为止。打开全屏的时候可以默认打开,或者在UIData中设置目标全屏的数据,在目标全屏打开后,根据UIData中的数据初始化全屏,比如切换标签,打开窗口等。
感谢王忠华@UWA问答社区提供了回答

A3:不要在UI显示上做太多的优化,太多的优化和封装反而是把简单的问题复杂化了,花费时间,逻辑混乱,学习成本提高。用最原始的解决方式,划分几个Layer,需要显示就直接SetActive。只有一个简单,无太多关联,易于理解,层次固定的UI显示系统,才能适应更多变化多样的需求。
感谢hy@UWA问答社区提供了回答

该问答来自UWA问答社区,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5c40292c08d1a36aad5af9ca


Lua

Q:我用UWA GOT Online这个工具检测了Lua内存,其中像这种Destroyed总数大于0的,从这个数据又看不出是什么东西要怎么处理呢?

请输入图片描述

UWA:Destroyed表示已经被Unity“销毁”,但是依然在Cache中被引用的对象数,如果总数稳定,其实问题是不大的。但如果一直有增加,那么确实需要尝试定位一下。

在SLua中有一个内置的Memory Profiler可以认为是这部分数据的加强版:会记录每个对象在被Destroyed之前,相关的组件或者GameObject的名字,比较方便排查。如果是ToLua,XLua等可能就得参考SLua的实现自己也做一个了,但因为机制其实差不多,所以比较容易照搬。

可以直接在SLua代码里搜这两个函数,看下思路:
ObjectCache.GetAlreadyDestroyedObjectNames();
ObjectCache.GetAllManagedObjectNames();

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


资源管理

Q:最近在项目中将场景打包成AssetBundle(以下简称AB)的时候发现包量会变的很大。分析之后发现是资源重复的问题。具体情况是这样的:

场景A,B,C 分别引用了Prefab M(M中包含其他资源,比如贴图T1,T2),这个时候按照我们的打包策略分析,最终会打出A.u,B.u,C.u,M.u4个AB包,按道理是没有问题的。但是我们查看了这四个包之后发现,共同依赖M里面的资源,比如贴图T1,T2在这四个AB包里面居然都会各存一份,而不是被剥离出来只保留引用,导致包量变大很多。最后自己试验的结果是,对场景打包,只有当我把M里面的资源也都单独拎出来打包,就是打出A.u,B.u,C.u,M.u,T1.u,T2.u,才会避免资源重复。

但是显然这样打包AB粒度太细了,我们项目的资源非常多,这样打包AB的数量会陡增,也不是很好的办法。目前只有在打场景AB才出现这种问题,其他类型的AB,打包都不会重复。我们用的是Unity 2017.4.1f1 (64-bit)版本。

请问大家,你们项目场景打包有遇到过这样的问题吗,有什么好的解决方法吗?

A:因为Prefab对Scene来说本来就是Clone,而不是Ref,打包时就完全没有Prefab这层关系了。比如Scene A、B、C都引用了PrefabD,打包时A、B、C内都会clone一份D(只有在Editor下编辑时才是ref + change的方式保存),换句话说Prefab D是完全可以不打包的,即使打了包,也和场景里的clone完全没关系。所以pfb没办法作为共享单元,而Prefab和scene引用的Texture是Ref,这个可以作为共享单元。

一个解法是升级到Unity 2018,新的Prefab机制应该是让Prefab对Scene属于Ref,而不是clone—看过其它同学测过、说过,自己没实际测过。

另外的解法就是抓大放小,这里Prefab(GameObject)一般不大,有冗余也就罢了,大头在Texture,所以Texture单独打AB总是要搞搞的。

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


UI

Q:怎么隐藏iPhone X底部横条?

A:2017的版本有这两个选项
请输入图片描述
如果没有上面的选项,可以通过修改导出Xcode工程中的这里(如果没有这段代码,加上去就行了)
请输入图片描述

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


Animation

Q:因为项目需要,想在Native代码中设置SkinnedMeshRenderer的骨骼Transform(Unity版本不限)。目前能找到的方法是,在选择不进行OptimizeGameObject的情况下,直接修改每个骨骼的Transform。有没有在OptimizeGameObject的情况下,仍然能设置骨骼结点的办法?

UWA:通用的方法很可能是没有的,就好比Dynamic Bone和Optimize GameObject不能共用一样。如果是想设置少量骨骼节点,那么可以尝试先将其Export出来,但如果是大量或随机的骨骼节点,那么很可能就没有办法达到了。

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


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

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

封面图来源:Crest Ocean Render
https://lab.uwa4d.com/lab/5b55ee58d7f10a201fd760a9