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
相关产品推荐
相关产品推荐

