如何通过Physics2D.OverlapPoint获取重叠的卡牌对象而非其碰撞体?
解决方法与优化方案
获取碰撞体对应的卡牌对象
你当前通过Physics2D.OverlapPoint拿到的是BoxCollider2D组件,要获取实际的卡牌对象,有两种常用方式:
1. 获取卡牌的GameObject
直接通过碰撞体的gameObject属性拿到挂载该碰撞体的卡牌对象:
Collider2D hit0 = Physics2D.OverlapPoint(positionPlH0, Cards); if (hit0 != null) { GameObject cardGameObject = hit0.gameObject; Debug.Log($"找到卡牌:{cardGameObject.name}"); // 确保InPlayCards数组类型为GameObject[] InPlayCards[0] = cardGameObject; }
2. 获取卡牌的自定义脚本实例
如果你的卡牌有自定义逻辑脚本(比如命名为Card),可以通过GetComponent直接获取脚本实例,方便后续操作卡牌的属性和方法:
// 假设你的卡牌脚本为Card Collider2D hit0 = Physics2D.OverlapPoint(positionPlH0, Cards); if (hit0 != null) { Card targetCard = hit0.GetComponent<Card>(); if (targetCard != null) { Debug.Log($"找到卡牌:{targetCard.name}"); // 确保InPlayCards数组类型为Card[] InPlayCards[0] = targetCard; } }
更优实现方案
1. 给Holder绑定专属管理脚本
避免手动维护数组索引与Holder的对应关系,给每个Holder挂载CardHolder脚本,让Holder自己管理当前放置的卡牌:
public class CardHolder : MonoBehaviour { public Card currentCard; private Collider2D _holderCollider; private void Awake() { _holderCollider = GetComponent<Collider2D>(); } // 检测指定位置是否在Holder范围内 public bool IsPositionInHolder(Vector2 position) { return _holderCollider.OverlapPoint(position); } // 放置卡牌并处理吸附逻辑 public void PlaceCard(Card card) { currentCard = card; // 将卡牌吸附到Holder位置 card.transform.position = transform.position; } }
在卡牌拖拽结束时,遍历所有Holder或者通过射线检测找到目标Holder,调用PlaceCard方法:
// 拖拽结束时的处理逻辑 void OnCardDragEnd(Vector2 mousePosition) { CardHolder targetHolder = null; // 遍历所有Holder找到包含鼠标位置的那个 foreach (var holder in FindObjectsOfType<CardHolder>()) { if (holder.IsPositionInHolder(mousePosition)) { targetHolder = holder; break; } } if (targetHolder != null && currentDraggingCard != null) { targetHolder.PlaceCard(currentDraggingCard); // 若仍需全局数组记录,可同步更新数组 // InPlayCards[holderIndex] = currentDraggingCard; } }
2. 使用碰撞体触发检测
给Holder设置IsTrigger=true,卡牌拖拽进入Holder区域时记录,松开时确认放置:
// 挂载在Card上的脚本 public class Card : MonoBehaviour { private CardHolder _currentHoverHolder; private void OnTriggerEnter2D(Collider2D other) { _currentHoverHolder = other.GetComponent<CardHolder>(); } private void OnTriggerExit2D(Collider2D other) { if (other.GetComponent<CardHolder>() == _currentHoverHolder) { _currentHoverHolder = null; } } // 拖拽结束时调用 public void OnDragEnd() { if (_currentHoverHolder != null) { _currentHoverHolder.PlaceCard(this); } } }
这种方式无需手动检测位置,利用Unity的碰撞系统自动识别Hover的Holder,逻辑更简洁。
内容的提问来源于stack exchange,提问作者TinyManager
相关产品推荐
相关产品推荐

