【unity】UI相关

ugui

1. UI层级关系

在unity中层级通常都是用数字表示的比如相机的Depth,Canvas的Order Layer
它们的参数都是数字,在显示上层级数字大的会覆盖层级数字小的
引擎渲染的时候,是按照数字从小到大依次渲染
那么就意味着后渲染的会覆盖之前渲染的,所以看起来就是遮挡住了之前的UI

1.决定UI显示顺序的因素
(1)不同的Camera的Depth
(2)相同Camera下的不同SortingLayer(oring Layers是在Edit->ProjectSettings->Tags&Layers中设置的)
(3)相同SortingLayer下的不同Z轴/Order in Layer
(4)UI在Hierarchy视图面板中的排列顺序:
在unity中Hierarchy上的物体是从上至下渲染的,也就是说,放到下面的UI会覆盖上面的UI

2.改变控件之间的层级关系
(1)同一canvas下:
1)改变控件transform的SiblingIndex
transform.GetSiblingIndex();
transform.SetSiblingIndex(int index);
index值越大,越后渲染,层级越大,越显示在前面
(2)不同Canvas下:
1)设置Canvas下的Sort Order
在同一个镜头中,canvas中所有的物体在进行渲染时,会按照先后顺序,即后渲染的会遮住先渲染的。因此在设定一些比如按钮的遮挡关系的时候。可以将想要在最上层的UI放到最后去渲染,修改Hierarchy层级面板从上往下的顺序。
但是UI的自然层级只有在没有指定sort之类的东西的时候才有效,在指定了渲染顺序后,以指定的顺序为优先

3.为什么UI摄像机和场景摄像机能协同工作
答案:UI摄像机和场景摄像机分别属于两个渲染层(Layer),所以它们之间的渲染互不干扰。它们工作得尽如人意(没有发生先后错乱,UI永远位于场景之上层)的原因就是因为摄像机深度(depth)控制的好。

2.ui屏幕适配

(1)为了避免上诉情况,选中“Canvas”,将 RenderMode 改为了 ScreenSpaceCamera,也就是让UI层在最终渲染时使用场景中配置的摄相机。然后将Render Camera 修改为我们场景中的摄像机, 这样子就可以让UI层与我们所控制的场景摄像机保持同步。
(2)Sorting Layer为变为Defauft,也就是和其它的游戏对象默认同一层,这样可能会存在,UI层被游戏对象档住的情况,所以我们Edit Layers, 在Sorting Layer中添加一个UI层,放到最低下,让它居于其它图层之上。
(3)然后我们可以再看到 Canvas Scaler (Script) 属性, 将 UI Scale Mode 修改为 Scale With Screen Size, 意思是让UI层随屏幕大小缩放。
(4)下面的Screen Match Mode是关键,我建议设置成“Shrink”,这样画布就是出屏幕原比例拉伸,
(5)设置Reference Resolution中的X、Y值为我们的游戏最终要使用主流屏幕像索数,这样子可以更好的所见即所得的设计出最终的显示效果。可能你改完Reference Resolution后,发现文字什么的变小了,没关系,可以调节Match来进行缩放。
(6)对于画布上的按钮,我们只需要修改它的锚点和轴心点及坐标
(7)先创建一个Image,尺寸修改为要添加的纹理实际尺寸大小
(8)修改返回图片的锚点和轴心点,一定要先修改锚点和轴心点之后改坐标才有意义!
(9)这样就能保证我们在画布下放入默认尺寸一样的背景图就可以充满屏幕,满足第一个基本要求,当然,这个背景图深度要最低,不能再上面加任何其他ui元素。

屏幕适配根本没有完美的解决方案,如果是全屏模块,那么锁定目标机型,将目标机型做成满屏,其他机型充满宽或高后留白(也叫留黑边)处理即可。

3.防止UI控件被点穿

(1) NGUI :利用 UICamera.hoveredObject 来判断,如果鼠标在 ui 上返回 true,否则返回 false。
使用一个可渲染的物体或者pannel,绑定boxcollider组件即可。如果你单用一个不可渲染的物体(这里点cao一下UIwiget),即使设定了大小和boxcollider,也是无法屏蔽的。(坑在这里)。
(2) UGUI :
①射线控制按钮,设置tag,如果碰到ui,返回true,只产生ui点击效果,否则产生对应的点击效果

4.ui优化

(1)DrawCall合并规则
①NGUI:Depth设置depth值,以UIPanel为单位,按照大小进行排序,相同材质进行合并
NGUI根据不同的DrawCall合并不同的网格UGUI以Canvas为单位,一个Canvas下的元素,合并成一个Mesh,不同的UI元素会以SubMeshes的形式存在。UGUI中如果一个Canvas中有很复杂的动态元素,尽量将静态元素拆分出来,确保更新的效率。
o拆分Canvas

②UGUI:hierarchy:重叠检测,分层合并,
控制FillAllDrawCalls
o拆分UIPanel
存在优势,也有一些问题,UGUI的合并规则是进行重叠检测,然后分层合并。下面的例子中,不同颜色代表不同图集
③所以在制作UI的时候,须要考虑层级关系,结合UGUI的合批规则,这样可以达到对drawCall的优化,

UI(图集使用和网格重建带来的影响)使用图集、动静分离
1)引起Canvas对网格的重建大概有几种情况Image,Text等UI元素的Enable及UI元素的长、宽或Color属性的变化等。因此在一些较复杂的界面,可以多分几个Canvas出来,虽然会增加drawcall,但是减少了网格重建时间,让性能有更好的提升。
2)摇杆区,技能区,血条,经验条是比较容易变化的,把这些都放到一个叫Dynamic的节点,并有自己的canvas,这样在他们频繁变化时,也只需要对这小部分进行网格重建,相对于整个MainUI重建的开销就小非常多了

参考:https://www.gameres.com/838828.html
在这里插入图片描述
第一个图,4种颜色,左边和右边数序相同,蓝色是0层,白色都是1层,这样会分层合批成4个DrawCall。
第二个图,左边的蓝色是0层,右边的黑色是0层蓝色是1层,这种情况下不会合批,所以会是9个drawCall
第三个图,把黑色延长到重叠的地方,黑色同处0层,所以DrawCall又降到了
(2)调试工具
•NGUI:DrawCall tool
•UGUI:Frame debugger
NGUI可以通过DrawCall tool看到多少个三角面,多少个widgets,通过观察widgets的关系,对NGUI层级直接调整,来进行合批。
NGUI使用drawcall tool,通过调整index,把相同材质的放在同一层。
UGUI用frame Debug看每个drawcall绘制了哪些东西,再做调整

OverDraw
•减少UI层叠
•遮挡场景时,关闭场景相机
•不用Image检测事件

5.降低界面的更新开销
•动静分离
•降低更新频率
•避免“敏感”操作
•优化选项

动静分离
在UGUI中细分Canvas下图中,血量和经验条会经常更新,如果在一个canvas中,PutGeometryJbFence和WaitngForJob,buildBatch出现的时候,表示更新的开销在子线程中,主线程处在一个等待的状态,差不多有5,6毫秒的等待。
拆分之后刚才的WaitingForJob等都没有了,动态的canvas开销就会很小。

降低更新的频率
•设定移动阈值
•设定更新频率
比如像小地图这样的界面,可能移动了一小段距离,小地图上更新了也不明显,可以通过设定阈值的方法,降低开销,或者直接设定更新时间。

5.UNITY把3D模型显示在UI层级上的思路

因此这里的做法是 使用镜子效果,做镜子可使用renderTexture
然后启用一个摄像机对renderTexture进行数据填充,
然后在ui上使用Raw Image控件,读取renderTexture来显示

6.怎么样能迅速找到某一个UI控件。

答案:分情况处理,这是一个优化策略的题目。首先如果这个控件我在awake的时候能知道,那么我会把它存成一个private变量,代码中使用的时候直接使用即可。如果不行,这个子物体是动态生成的(他可能有或者没有),那尽量使用FindChild,得到之后加以判断。如果不得不全局找一个东西(比如找到角色物体),才会用Find。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烧仙草奶茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值