UI事件依赖于Graphic Raycast组件,必须绑在Canvas上,表示这个Canvas下所有UI元素支持的事件,如果不想这个Canvas下的UI不接收UI事件,可以关闭(enable=false)或者删除组件
UGUI的点击事件也基于射线,如果不需要响应事件,千万不要勾选RaycastTarget。UI事件会在EventSystem的Update方法中调用Process时触发。UGUI会遍历屏幕中所有Raycast是true的UI,接着就会发射线,并且排序找到玩家最先触发的那个UI,在抛出事件给逻辑层去响应,这样无形会带来很多开销。
事件接口
(1)IScrollHandler-OnScroll:鼠标滚轮持续时调用
(2)IIDropHandler-OnDrop:落下时调用
(3)IIUpdateSelectedHandler-OnUpdateSelected 选择时持续调用,只针对Selectable组件
(4)ISelectHandler - OnSelect:选择后调用,只针对Selectable组件
(5)IDeselectHandler - OnDeselect:取消选择,由于只能选择一个Selectable,当选择新的 后,之前选择的就会回调取消选择事件
(6)IMoveHandler - OnMove: 选择后,可以监听上下左右WASD方向键。访问(6)eventData.moveDir,可以取到具体移动的方向
ExecuteEvents帮助类,可以用来发送IEventSystemHandler事件到游戏对象。
ExecuteEvents.Execute();
渲染排序
1,Camera中depth优先最高,越大越靠上
2,sorting layer 优先级越靠上越优先
3,order layer同一个sorting layer下越大越优先
如果想改变同一个Canvas下的默认从上到下的渲染层序,在这个UI组件上增加Canvas组件,然后比父节点的Canvas的sortinglayer大就可以了
获取鼠标下所有RaycastResult的物体
List results = new List();
EventSystem.current.RaycastAll(data, results);
Canvas Scale屏幕自适应,首选Expand
(1) Expand:表示Canvas下的UI始终保持在屏幕内,当屏幕宽度变窄后,它会整体缩放高度来保持自适应。
(2) Match Width Or Height:始终保持宽度或高度来自适应高度或宽度
(3) Shrink:当分辨率发生变化时,始终保持原始比例,超出屏幕部分会被裁切掉(显示不全)、
Content Size Fitter
该组件可以重新计算子对象的RectTransform区域,如果子对象很多的话,效率不高。可能出于效率的考虑,ContentSizeFitter需要等一帧才能算出正确的区域。如果想要立即取到正确的区域,调用LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform)
Canvas优化
UGUI会自动合并批次,原理是它会把一个Canvas下的所有元素合并在一个Mesh里。如果Canvas下的元素很多,任意一个元素发生位置、大小的改变,就需要重新合并所有元素,如果元素很多的话,可能就会产生卡顿。
解决方法:每个UI界面都设置成一个Canvas。如果这个界面下的元素很多,可以考虑多套几个Canvas。尤其是会频繁改变位置大小的元素,这样就可以降低它合并Mesh的开销。Canvas套的太多也不好,Mesh合并降低了,但是DrawCall又上去了,因为每个Canvas都会单独占用一个DrawCall
Atlas
Canvas会自动合并下面所有元素到一个Mesh中。Mesh虽然合并在一起,但是如果贴图是分开的,那么每个贴图依然会多占用一个DrawCall。为了减少DrawCall,可以将多张图合并在一个图片中,这称为Atlas(图集)
创建Atlas:
(1) 在EditProject中SpritePacker Mode中选择AlwaysEnabled
(2) Project面板中右键Create→SpriteAtlas
(3) 在Objects for Packing中添加需要加入的图集,在点击PackPreview生成
通过SpriteAtlas中的GetSprite(“路径”);获取图集中Sprite
不规则图片事件响应
通过Image.alphaHitTestMinimumThreshold(0-1):默认为0,当图片的alpha小于这个值时不会响应,需要将图片的Read/Write Enabled打开