unity5, UGUI刺穿问题解法

我希望在touch屏幕时player起跳,于是在playerControl.cs的Update函数中添加如下touch代码:           

  if (Input.GetMouseButtonDown (0)) {//left button down
        jump ();
   }

同时我在屏幕左上角加了一个实现暂停的pause按钮,用的是Unity的UI Button。

于是问题来了,当我点pause按钮想暂停时,人物同时也会起跳!

即Button响应touch消息后并没能把它拦截下来,touch消息刺穿Button到达了屏幕。

解决UGUI刺穿问题目前在所有平台都有效的办法是在屏幕响应touch前先用graphicRaycaster当前touch是否落在ui上。

举例说明如下:

假设我的项目UI部分Hierarchy如下:

在UI节点上的脚本UIcontrol.cs中实现如下函数:

using UnityEngine.EventSystems;
using System.Collections.Generic;

using UnityEngine.UI; 

   public bool isTouchOnUI()
    {
        EventSystem eventSystem = gameObject.transform.FindChild ("EventSystem").GetComponent<EventSystem> ();
        Transform[] childrenTransformList = GetComponentsInChildren<Transform>();
        foreach (Transform transform in childrenTransformList) {
            GraphicRaycaster graphicRaycaster = transform.GetComponent<GraphicRaycaster> ();
            if (graphicRaycaster&&graphicRaycaster.enabled==true) {
                PointerEventData eventData = new PointerEventData (eventSystem);
                eventData.pressPosition = Input.mousePosition;
                eventData.position = Input.mousePosition;
                List<RaycastResult> list = new List<RaycastResult> ();
                graphicRaycaster.Raycast (eventData, list);

          ////Debug.Log("list.Count:"+list.Count);
                if (list.Count > 0)
                    return true;
            }
        }
        return false;
    }

那么前面的touch代码改为:

        bool isTouchOnUI=m_gameRef.transform.Find("UI").GetComponent<UIcontrol>().isTouchOnUI();
            if (isTouchOnUI==false&&Input.GetMouseButtonDown (0)) {//left button down
                jump ();
            }

即可解决touch穿透问题。

补充:

一,一定要加if(graphicRaycaster)的判断,因为注意GameObject.GetComponentsInChildren的文档中写道:

Returns all components of Type type in the GameObject or any of its children.

即,除了UI节点的孩子会被搜索以外,UI节点本身也会被搜索,而UI节点上不含有graphicRaycaster,所以必须先判断graphicRaycaster是否获得成功,再进行后续处理。

另外文档中还写道:

The search for components is carried out recursively on child objects, so it includes children of children, and so on.

即GameObject.GetComponentsInChildren不只是会搜索子节点,也会搜索孙节点。

二,加上graphicRaycaster.enabled==true的判断,好处是,如果我们希望某个Canvas能被刺穿,则可以将其Graphic Raycaster去掉勾选即可。

参考:http://www.cnblogs.com/fly-100/p/4570366.html

原文地址:https://www.cnblogs.com/wantnon/p/4606577.html