当前位置:   article > 正文

「Unity3D」(2)射线检测与EventSystem判断UI点击_射线检测点击和event检测 哪个好

射线检测点击和event检测 哪个好

按照传统的做法,EventSystem用做UI的事件处理,射线检测用做非UI碰撞的判断,但需要手动添加Collider。EventSystem使用了,GraphicRaycaster组件来检测UI元素的事件,其底层还是使用了射线来检测碰撞的。

虽然UI组件勾选Raycast Target能够按照层级关系阻挡穿透,但其阻挡的是UI组件之间的射线穿透。GraphicRaycaster的源码中有 var foundGraphics = GraphicRegistry.GetGraphicsForCanvas(canvas);只会判断Graphic对象,这是UI元素的父类。

那么,手动的射线就会有穿透UI的问题,所以我们需要一个能判断UI元素被点击的需求,看代码封装。

/// <summary>
/// Whether touch down or mouse button down over UI GameObject.
/// </summary>
public static bool IsClickDownOverUI()
{
    #if UNITY_EDITOR
    if (Input.GetMouseButtonDown(0))
    #else
    if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Began)
    #endif
    {
        #if UNITY_EDITOR
        if (EventSystem.current.IsPointerOverGameObject())
        #else
        if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
        #endif
        {
            return true;
        }
    }

    return false;
}


/// <summary>
/// Whether touch up or mouse button up over UI GameObject.
/// </summary>
public static bool IsClickUpOverUI()
{
    #if UNITY_EDITOR
    if (Input.GetMouseButtonUp(0))
    #else
    if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Ended)
    #endif
    {
        #if UNITY_EDITOR
        if (EventSystem.current.IsPointerOverGameObject())
        #else
        if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
        #endif
        {
            return true;
        }
    }

    return false;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 这里给出了click down和up的分别判断。
  • 封装了鼠标和触摸的判断。
  • 函数返回true表明UI元素被点中。

射线检测

原理是,根据屏幕的点击,手动发射一条射线,然后获取碰撞的对象。

/// <summary>
/// Raycast a ray from touch up or mouse button up and test whether hit transform,
/// if hit transform return it or return null.
/// [isCheckHitUI] Whether check ray hit ui transform,
/// if hit ui just return null.
/// </summary>
public static Transform Raycast(bool isCheckHitUI = true)
{
    #if UNITY_EDITOR
    if (Input.GetMouseButtonUp(0))
    {
        if (isCheckHitUI)
        {
            if (EventSystem.current.IsPointerOverGameObject())
            {
                return null;
            }
        }

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    #else
    if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Ended)
    {
        if (isCheckHitUI)
        {
            if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
            {
                return null;
            }
        }

        Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
    #endif

        RaycastHit hit;

        if (Physics.Raycast(ray, out hit))
        {
            // or hit.collider.transform;
            return hit.transform; 
        }
    }

    return null;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • isCheckHitUI 表示UI是否会阻挡射线的选择,点中UI直接返回null。
  • Camera.main 代表的是拥有Tag MainCamera的Camera。
  • 封装了鼠标和触摸的操作。
  • 射线点中了带有Collider的非UI元素,就会返回其Transform。

「老问题了,更好的实践,看后续」

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/101041
推荐阅读
相关标签
  

闽ICP备14008679号