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)
{
}
}
所以对于我的场景,我有一个 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)
{
}
}