Unity Check overlap of rect works 除非在 gridlayoutgroup 中

Unity Check overlap of rect works except if in gridlayoutgroup

所以对于我的场景,我有一个 Item 和一个 Slot 脚本。如果 Slot 脚本应用于 GridLayoutGroup 中的 UI,它不会读取,即使它是否悬停也是如此。但是,如果 Slot UI 对象不在内部 GridLayoutGroup,它会读取重叠。

以下是脚本。我目前基于 35px 的比例进行测试。

Slot.cs

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

public class Slot : MonoBehaviour, IDragHandler, IDropHandler
{

    public RectTransform Item_DragRect
    {
        get
        {
            if(Item_CS.Item_Dragged != null)
            {
                return Item_CS.Item_Dragged.GetComponent<RectTransform>();
            }
            else
            {
                return null;
            }
        }
    }
    public RectTransform rectTransform;
    public Rect DisplayRect;

    public Color D_Color;
    public Color O_Color;
    public Color T_Color;
    public GameObject CurrItem;

    // Start is called before the first frame update
    void Start()
    {
        rectTransform = this.GetComponent<RectTransform>();
    }

    // Update is called once per frame
    public void FixedUpdate()
    {
        DisplayRect = new Rect(rectTransform.localPosition.x, rectTransform.localPosition.y, rectTransform.rect.width, rectTransform.rect.height);
        if (Item_DragRect != null)
        {
            CurrItem = Item_DragRect.gameObject;
            Rect myRect = new Rect(rectTransform.localPosition.x, rectTransform.localPosition.y, rectTransform.rect.width, rectTransform.rect.height);
            Rect ItemRect = new Rect(Item_DragRect.localPosition.x, Item_DragRect.localPosition.y, Item_DragRect.rect.width, Item_DragRect.rect.height);

            if (ItemRect.Overlaps(myRect))
            {
                GetComponent<Image>().color = O_Color;
            }
            else
            {
                GetComponent<Image>().color = D_Color;
            }
        }
        else
        {
            CurrItem = null;
            GetComponent<Image>().color = D_Color;
        }
    }
    public void OnDrag(PointerEventData eventData)
    {

    }

    public void OnDrop(PointerEventData eventData)
    {

    }
}

Item_CS.cs

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

public class Item_CS : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerEnterHandler, IPointerExitHandler
{
    public static GameObject Item_Dragged;
    public GameObject CurrID;
    public Vector2 MyScale;
    private Vector3 ItemPos;




    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        RectTransform rectTransform = this.GetComponent<RectTransform>();
        rectTransform.sizeDelta = new Vector2(MyScale.x * 35, MyScale.y * 35);
        DragFunction();
        CurrID = Item_Dragged;
    }

    public void DragFunction()
    {
        if(Item_Dragged != null)
        {
            Item_Dragged.transform.SetAsLastSibling();
        }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if(Item_Dragged == null)
        {
            Item_Dragged = gameObject;
            GetComponent<CanvasGroup>().blocksRaycasts = false;
        }
        else
        {
            Item_Dragged = gameObject;
            GetComponent<CanvasGroup>().blocksRaycasts = false;
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        this.transform.position = Input.mousePosition;       
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        Item_Dragged = null;
        GetComponent<CanvasGroup>().blocksRaycasts = true;
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        //throw new System.NotImplementedException();
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        //throw new System.NotImplementedException();
    }
}

RectTransform 非常棘手。您的 localPosition 将根据您设置的锚点而有所不同。您应该调试并检查 localPosition returns 所需的值,而且 localPosition 在使用 RectTransform 时对我来说从来没有用过,我认为您不应该将它与 RectTransform 一起使用,我想它是 属性 继承自 Transform 而您可能应该使用 anchoredPosition 和 pivot 来计算你的 rect 位置。

查看图片。我只是记录了那个 rectTransform 的 localPosition,这完全是胡说八道,我不知道 146,-300 是如何变成 -574、1180,我的 CanvasScaller 的比例是 4.95,所以它不会以任何方式计算

另一方面,锚定位置完全符合预期:

事实证明,这是因为父对象通过将其添加到当前位置而取消了其位置变换,因此添加了一个简单的检查,看看插槽父对象是否具有 gridlayoutgrid,如果是,则可以抵消差异

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

public class Slot : MonoBehaviour, IDragHandler, IDropHandler
{

    public RectTransform Item_DragRect
    {
        get
        {
            if(Item_CS.Item_Dragged != null)
            {
                return Item_CS.Item_Dragged.GetComponent<RectTransform>();
            }
            else
            {
                return null;
            }
        }
    }
    public RectTransform rectTransform;
    public RectTransform rectParent;
    public Rect DisplayRect;

    public Color D_Color;
    public Color O_Color;
    public Color T_Color;
    public GameObject CurrItem;

    // Start is called before the first frame update
    void Start()
    {
        rectTransform = this.GetComponent<RectTransform>();
        if(GetComponentInParent<GridLayoutGroup>() != null)
        {
            rectParent = GetComponentInParent<GridLayoutGroup>().GetComponent<RectTransform>();
        }
        else
        {
            rectParent = null;
        }

    }

    // Update is called once per frame
    public void FixedUpdate()
    {
        DisplayRect = new Rect(rectTransform.transform.position.x, rectTransform.transform.position.y, rectTransform.rect.width, rectTransform.rect.height);
        if (Item_DragRect != null)
        {
            CurrItem = Item_DragRect.gameObject;
            if(rectParent != null)
            {
                Rect myRect = new Rect(rectTransform.localPosition.x + rectParent.localPosition.x, rectTransform.localPosition.y + rectParent.localPosition.y, rectTransform.rect.width, rectTransform.rect.height);
                Rect ItemRect = new Rect(Item_DragRect.localPosition.x, Item_DragRect.localPosition.y, Item_DragRect.rect.width, Item_DragRect.rect.height);

                if (ItemRect.Overlaps(myRect))
                {
                    GetComponent<Image>().color = O_Color;
                }
                else
                {
                    GetComponent<Image>().color = D_Color;
                }
            }
            else
            {
                Rect myRect = new Rect(rectTransform.localPosition.x, rectTransform.localPosition.y, rectTransform.rect.width, rectTransform.rect.height);
                Rect ItemRect = new Rect(Item_DragRect.localPosition.x, Item_DragRect.localPosition.y, Item_DragRect.rect.width, Item_DragRect.rect.height);

                if (ItemRect.Overlaps(myRect))
                {
                    GetComponent<Image>().color = O_Color;
                }
                else
                {
                    GetComponent<Image>().color = D_Color;
                }
            }


        }
        else
        {
            CurrItem = null;
            GetComponent<Image>().color = D_Color;
        }
    }
    public void OnDrag(PointerEventData eventData)
    {

    }

    public void OnDrop(PointerEventData eventData)
    {

    }
}