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

Camera.main.ScreenToWorldPoint工作异常,2D场景选最近物体出错

问题分析与修复方案

核心问题1:鼠标世界坐标计算错误

正交相机下,ScreenToWorldPoint的z参数代表从相机到目标平面的距离,你直接给鼠标坐标叠加Vector3(0,0,10)会导致世界坐标偏移,无法准确对应鼠标在2D平面的位置。正确做法是给Input.mousePosition的z值设置为相机到2D物体所在平面的距离(通常2D物体在z=0平面,若相机位于z轴负方向,z值设为相机z坐标的绝对值即可)。

核心问题2:最近物体筛选逻辑错误

你的代码中找到更近的物体时,仅更新了选中的碰撞体变量c,但未同步更新distance变量。这会导致distance始终保持初始的Mathf.Infinity,所有物体的距离都会小于它,最终c会被赋值为循环中最后一个遍历到的物体,而非真正距离鼠标最近的那个。

修正后的代码

if (Input.GetMouseButtonDown(1))
{
    // 正确计算鼠标世界坐标(适配正交相机)
    var mouseScreenPos = Input.mousePosition;
    // 假设2D物体在z=0平面,设置z为相机到z=0平面的距离
    mouseScreenPos.z = Mathf.Abs(Camera.main.transform.position.z);
    var mouseWorldPos = Camera.main.ScreenToWorldPoint(mouseScreenPos);

    Collider2D[] colliders = Physics2D.OverlapCircleAll(mouseWorldPos, 10, greenery);
    float closestDistance = Mathf.Infinity;
    Collider2D closestCollider = null;

    foreach (var collider in colliders)
    {
        float currentDistance = Vector2.Distance(mouseWorldPos, collider.transform.position);
        if (currentDistance < closestDistance)
        {
            closestDistance = currentDistance;
            closestCollider = collider;
        }
    }

    if (closestCollider != null)
    {
        // 执行你的删除逻辑,例如:
        // Destroy(closestCollider.gameObject);
        Debug.Log($"选中最近物体:{closestCollider.gameObject.name}");
    }
}

额外优化建议

  • 提前缓存Camera.main,避免每帧重复查找消耗性能:
    private Camera mainCam;
    void Awake() 
    { 
        mainCam = Camera.main; 
    }
    
    之后代码中用mainCam替代Camera.main即可。
  • 若物体碰撞体的中心与transform位置不一致,可改用collider.bounds.center计算距离,结果会更准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:00:04