You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:05:22