UI遮擋3D物體響應(yīng)

問題1: 解決UI和3D物體層疊問題,只響應(yīng)UI的問題

先看看當(dāng)點擊3D物體和UI響應(yīng)事件的代碼,一般點擊UI使用IPointerClickHandler接口和OnPointerClick函數(shù),點擊3D物體時使用OnMouseDown函數(shù)。
點擊UI代碼

public class CollideUI : MonoBehaviour,IPointerClickHandler {
    private int _index;
    public void ChangeColor()
    {
        if (_index == 0)
        {
            GetComponent<Image>().color = Color.blue;
        }
        else
        {
            GetComponent<Image>().color = Color.white;
        }
        _index = _index == 0 ? 1 : 0;
    }
    public void OnPointerClick(PointerEventData eventData)
    {
        ChangeColor();
    }
}

點擊3D物體代碼

public class CollideCube : MonoBehaviour
{
    private int _index=0;
    private void OnMouseDown()
    {
        ChangeColor();
    }
    private void ChangeColor()
    {
        if (_index == 0)
        {
            GetComponent<MeshRenderer>().material.SetColor("_Color", Color.black);
        }
        else
        {
            GetComponent<MeshRenderer>().material.SetColor("_Color",Color.white);
        }
        _index = _index == 0 ? 1 : 0;
    }
}

但當(dāng)點擊后重疊3D物體的UI后響應(yīng)的事件會穿透UI同時響應(yīng)3D物體,事件如下所示


image.png

如何解決這一問題,我們可以在3D物體上也使用IPointerClickHandler接口以及OnPointerClick函數(shù),但是需要在攝像機(jī)上加上Physics Raycaster組件,這樣就不會出現(xiàn)穿透問題。
點擊3D物體代碼修改如下

public class CollideCube : MonoBehaviour,IPointerClickHandler
{
    private int _index=0;
    public  void ChangeColor()
    {
        if (_index == 0)
        {
            GetComponent<MeshRenderer>().material.SetColor("_Color", Color.black);
        }
        else
        {
            GetComponent<MeshRenderer>().material.SetColor("_Color",Color.white);
        }
        _index = _index == 0 ? 1 : 0;
    }
    public void OnPointerClick(PointerEventData eventData)
    {
        ChangeColor();
    }
}

如此點擊疊加處UI后不會出現(xiàn)點擊穿透問題


image.png
問題二:解決UI和3D物體的同時響應(yīng)問題

除了上面3D物體使用OnMouseDown函數(shù)以外,我們想要同時響應(yīng)并且同時都使用IPointerClickHandler,這樣看起來比較整體。我們只需要修改點擊UI方面的代碼即可。代碼如下

public class CollideUI : MonoBehaviour,IPointerClickHandler {
    private int _index;
    public void OnPointerClick(PointerEventData eventData)
    {
        ChangeColor();
        ExecuteAll(eventData);
    }
    public void ChangeColor()
    {
        if (_index == 0)
        {
            GetComponent<Image>().color = Color.blue;
        }
        else
        {
            GetComponent<Image>().color = Color.white;
        }
        _index = _index == 0 ? 1 : 0;
    }
    public void ExecuteAll(PointerEventData data)
    {
        List<RaycastResult> results = new List<RaycastResult>();
        //獲取所有射線射中的物體并返回結(jié)果列表results
        EventSystem.current.RaycastAll(data, results);
        foreach (var result in results)
        {
            if (result.gameObject != this.gameObject)
            {
                //執(zhí)行所有點擊中的函數(shù)
                ExecuteEvents.Execute(result.gameObject,data,ExecuteEvents.pointerClickHandler);
            }
        }
    }
}
image.png
問題三:解決UI和鼠標(biāo)點擊之間的響應(yīng)問題

當(dāng)我有3D物體為只要點擊屏幕任何地方都會響應(yīng)事件的函數(shù),那這時候當(dāng)我點擊UI時候這個3D物體也會同時響應(yīng)。
點擊到UI后同時響應(yīng)

點擊鼠標(biāo)代碼如下,掛載在3DCub。

public class ClickMouse : MonoBehaviour {
    private int _index=0;
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            ChangeColor();
        }
    }
    public void ChangeColor()
    {
        if (_index == 0)
        {
            GetComponent<MeshRenderer>().material.SetColor("_Color", Color.black);
        }
        else
        {
            GetComponent<MeshRenderer>().material.SetColor("_Color", Color.white);
        }
        _index = _index == 0 ? 1 : 0;
    }
}

這時候我們想當(dāng)我們點擊到UI后不響應(yīng)鼠標(biāo)點擊事件。代碼如下:

public class ClickMouse : MonoBehaviour {
    private int _index=0;
    GraphicRaycaster _raycaster;
    private void Start()
    {
        _raycaster = FindObjectOfType<GraphicRaycaster>();
    }
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            ChangeColor();
        }
    }
    public void ChangeColor()
    {
        if (_index == 0&& !IsUI())
        {
            GetComponent<MeshRenderer>().material.SetColor("_Color", Color.black);
        }
        else
        {
            GetComponent<MeshRenderer>().material.SetColor("_Color", Color.white);
        }
        _index = _index == 0 ? 1 : 0;
    }
    private bool IsUI()
    {
        PointerEventData data = new PointerEventData(EventSystem.current);
        data.pressPosition = Input.mousePosition;
        data.position = Input.mousePosition;
        List<RaycastResult> result = new List<RaycastResult>();
        _raycaster.Raycast(data, result);
        return result.Count > 0;
    }
}

這時候當(dāng)我們點擊除開UI的地方都會響應(yīng)Cube的事件,當(dāng)我們點擊中UI后只會響應(yīng)UI事件


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容