怎样处理ngui Panel多层次事件响应异常的问题,我也不是很熟,就给大家分享一下别人的文章。

在使用NGUI的panel时,当两次Panel重叠时,当点击前面面板,后面版面按钮可能会被响应。这是因为NGUI将UI控件都当做3D世界中的物体来做碰撞体,当做射线碰撞时,才通过UICamera响应响应的事件,但是由于Panel没有碰撞体,则射线直接穿过,碰撞到后面的Button(自带box collider)上,因此,出现这种响应异常。刚刚学习NGUI,发现有此问题,不知道NGUI是否已经提供解决方法,有了解的大大请帮忙指点,这里暂时自己弄了个临时方法来避免这种情况发生。

1.在NGUITools中添加如下方法:

  1. //add  for reCalculate collider bounds referenece AddWidgetCollider
  2. static public void RecalculateColliderBounds(GameObject go)
  3. {
  4. if (go != null)
  5. {
  6. BoxCollider box = go.GetComponent<Collider>() as BoxCollider;
  7. if(box==null)
  8. return;
  9. int depth = NGUITools.CalculateNextDepth(go);
  10. Bounds b = NGUIMath.CalculateRelativeWidgetBounds(go.transform);
  11. box.isTrigger = true;
  12. box.center = b.center + Vector3.back * (depth * 0.25f);
  13. box.size = new Vector3(b.size.x, b.size.y, 0f);
  14. }
  15. }
  16. //remove collider from widget
  17. static public void RemoveColliderFromWidget(GameObject go)
  18. {
  19. if(go!=null)
  20. {
  21. BoxCollider box = go.GetComponent<Collider>() as BoxCollider;
  22. if(box==null)
  23. return ;
  24. if (Application.isPlaying)
  25. GameObject.Destroy(box);
  26. else
  27. GameObject.DestroyImmediate(box);
  28. }
  29. }

这个方法主要参照AddWidgetCollide方法,RecalculateColliderBounds方法主要完成对添加box collider的panel,重新计算其下子控件所组成的一个外围区域。RemoveColliderFromWidget方法提供给编辑器器一个手动设置Panel是否是collider的机会。

2.在UIPanel中添加如下代码:
  1. //whether this panel is collider panel
  2. public bool isColliderPanel=false;
  3. public bool IsColliderPanel{
  4. get{ return isColliderPanel;}
  5. set{
  6. this.isColliderPanel=value;
  7. if(this.isColliderPanel)
  8. {
  9. NGUITools.AddWidgetCollider(this.gameObject);
  10. }else
  11. {
  12. NGUITools.RemoveColliderFromWidget(this.gameObject);
  13. }
  14. }
  15. }
添加了个是否是collider的选项,方便设置是否是带碰撞功能的panel

在void LateUpdate ()函数最后添加NGUITools.RecalculateColliderBounds(this.gameObject);随时更新collider外围方块区域。

3.在UIPanelInspector中OnInspectorGUI ()函数最后添加编辑器选项:
  1. GUILayout.BeginHorizontal();
  2. bool isColliderPanel = EditorGUILayout.Toggle("Is Collider", panel.IsColliderPanel, GUILayout.Width(100f));
  3. GUILayout.Label("whether the panel need collider");
  4. GUILayout.EndHorizontal();
  5. if (panel.IsColliderPanel != isColliderPanel)
  6. {
  7. panel.IsColliderPanel = isColliderPanel;
  8. EditorUtility.SetDirty(panel);
  9. }
应该这就这些了,这样可以随时指定当前panel是否带collider。效果如下图:
NGUI-解决Panel多层次事件响应异常。