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

Unity:创建Card对象后如何不松鼠标直接切换至该对象响应拖拽

解决Unity 2D卡牌游戏中Deck生成Card后直接拖拽的问题

问题核心在于:Unity的鼠标事件流默认绑定到首次接收OnMouseDown事件的对象,你直接调用Card的OnMouseDrag只是单次执行方法,不会让Unity把后续拖拽事件持续发送给新生成的Card。下面是两种可行的解决方案:

方法1:让Card接管鼠标事件流

在Deck的OnMouseDown中生成Card后,先触发Card的OnMouseDown建立拖拽初始状态,再强制让Card成为鼠标事件的接收目标,后续OnMouseDrag就会自动触发。

Deck脚本代码

using UnityEngine;

public class Deck : MonoBehaviour
{
    public GameObject cardPrefab;

    void OnMouseDown()
    {
        // 在Deck上方生成Card(可调整偏移量适配布局)
        Vector3 spawnPos = transform.position + new Vector3(0, 1f, 0);
        GameObject newCard = Instantiate(cardPrefab, spawnPos, Quaternion.identity);
        Card cardComp = newCard.GetComponent<Card>();

        // 触发Card的OnMouseDown,初始化拖拽状态
        cardComp.OnMouseDown();
        // 让EventSystem将后续鼠标事件定向到Card
        UnityEngine.EventSystems.EventSystem.current.SetSelectedGameObject(newCard);
    }
}

Card脚本代码

using UnityEngine;

public class Card : MonoBehaviour
{
    private bool _isDragging;
    private Vector3 _mouseOffset;

    void OnMouseDown()
    {
        _isDragging = true;
        // 计算鼠标与卡片中心的偏移,避免拖拽时卡片瞬移到鼠标位置
        Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        mouseWorldPos.z = 0; // 2D场景固定Z轴
        _mouseOffset = transform.position - mouseWorldPos;
    }

    void OnMouseDrag()
    {
        if (!_isDragging) return;
        
        Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        mouseWorldPos.z = 0;
        transform.position = mouseWorldPos + _mouseOffset;
    }

    void OnMouseUp()
    {
        _isDragging = false;
        // 释放事件绑定
        UnityEngine.EventSystems.EventSystem.current.SetSelectedGameObject(null);
    }
}

方法2:手动模拟拖拽逻辑

如果因EventSystem冲突导致方法1失效,可以在Deck的OnMouseDown生成Card后,直接在Deck的OnMouseDrag中代理Card的移动逻辑,直到鼠标松开:

// 修改后的Deck脚本
using UnityEngine;

public class Deck : MonoBehaviour
{
    public GameObject cardPrefab;
    private Card _currentDraggingCard;
    private Vector3 _mouseOffset;

    void OnMouseDown()
    {
        Vector3 spawnPos = transform.position + new Vector3(0, 1f, 0);
        GameObject newCard = Instantiate(cardPrefab, spawnPos, Quaternion.identity);
        _currentDraggingCard = newCard.GetComponent<Card>();

        // 初始化偏移量
        Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        mouseWorldPos.z = 0;
        _mouseOffset = _currentDraggingCard.transform.position - mouseWorldPos;
    }

    void OnMouseDrag()
    {
        if (_currentDraggingCard == null) return;
        
        Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        mouseWorldPos.z = 0;
        _currentDraggingCard.transform.position = mouseWorldPos + _mouseOffset;
    }

    void OnMouseUp()
    {
        _currentDraggingCard = null;
    }
}

注意事项

  • 确保Deck和Card都有Collider2D组件(Unity的OnMouse系列事件必须依赖Collider才能触发)
  • 如果是UI卡牌(基于Canvas渲染),建议改用IPointerDownHandler、IPointerDragHandler等UGUI事件接口,适配UI事件系统

内容的提问来源于stack exchange,提问作者Weed OK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:57:27