NGUI按钮OnClick丢失问题跟进记录(按钮点击不灵敏)

发表于2016-03-24
评论1 5.7k浏览

  注1:本文之前发表在项目K吧中的,后来在另一个项目中,发现了有类似的问题,这类问题具有共通性,so将文章再公开转发一次,仅供参考。

  注2:本文跟进的是Unity的NGUI组件,但原理在UGUI中也适用。

 

一、从问题说起

最近接到反馈,UI响应不灵敏,经常要点几下才有反馈,经跟进以后,发现按钮有OnClick事件丢失的现象。问题现象演示:


 

 

  正常表现演示:


 

 

  菜单按钮响应区域:


 

由上面的问题演示可见,菜单按钮,实际上是响应了点击,已经在执行点击动画了,但是侧边栏没有同步响应。侧边栏的显隐是通过OnClick事件触发的,而动画是通过OnPressTrue事件触发的,可以断定,在某次点击过程中,OnPress响应了,而Onclick事件丢失了,并且在Collider边缘点击时,发生的概率很大。

是什么原因导致Collider的OnPress事件触发而OnClick事件没有触发?NGUI的bug?Unity的物理碰撞检测问题?

  先看看NGUI中,处理OnClick与OnPress的地方:

  (UICamera,  ProcessRelease, ln 1841)


  可以看到,在OnPress与OnClick之间,两个条件判断,可以断定,在某种情况下出现了不满足OnClick的情况,导致OnClick没有被触发。

   这简单,log之,发现问题出在“currentTouch.pressed == currentTouch.current”这句。

   回顾下NGUI的点击处理流程: 



  由于需要一个press down + press up 才能构成一个click,OnClick事件的触发,通常要比OnPress晚几帧。在本例中,OnPress与OnClick大概相差5-6帧。

   在这5帧中,在点击位置不变的情况下,出现了点击到的Collider发生变化,导致了“currentTouch.pressed == currentTouch.current”条件不符。



  已经快要接近问题的真相了~

  问题症结点:

  (UICamera,  ProcessFakeTouches, ln 1575)


  在按下去后抬起来之前,某帧中,RayCast获取到的Object,改变了。为什么呢?blablabla……

最后,发现是由于按钮中内嵌的tweenScale组件,响应了Onpress函数,在下一帧开始对按钮做Scale缩放,导致Collider变小,RayCast获取不到,这也就是为什么在Collider的边缘区域点击,出现概率会很大。(由alberzhu(朱新铭)协助找到原因)


 

  问题解决方案(二选一):

1、将缩小动画改为放大

2、将tween的缩放事件响应改为OnClick,与Button一致

  该问题采用了方案2解决,改变tween的响应为Onclick,与Button组件一样,控件的整体响应表现应该保持一致。

-------------分割线----160111补充------------

以上解决方案,是在项目面临上线,处于风险考虑,要求最小改动而选择的方案,实际上都不是最优的方案。

将响应区跟底图表现分离,在响应区不变的情况下,仅对底图做按、弹等缩放动画表现,更符合交互习惯。

 

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引