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

Unity透视相机下ScreenToWorldPoint始终返回相机位置问题求助

透视相机下ScreenToWorldPoint获取触摸世界坐标的问题解决方法

问题根源

你当前代码的核心问题是对ScreenToWorldPoint的z参数理解错误:透视相机中,这个z值是相机本地空间下的深度(即沿相机前向轴,从相机到目标平面的距离),而非世界空间的坐标值。你直接取-Camera.main.transform.position.z,在相机位置或旋转变化时,这个值完全无法对应正确的深度平面,导致返回结果始终是相机位置。

修正方案

方案1:固定深度平面获取坐标

如果你需要触摸点在相机前方固定距离平面上的世界坐标,直接传入相机前向的深度值(正数表示相机前方):

Vector2 screenPosition = Input.touches[0].position;
// 设置目标平面距离相机10米(可根据需求调整)
Vector3 worldPos = Camera.main.ScreenToWorldPoint(new Vector3(screenPosition.x, screenPosition.y, 10f));
Vector2 touchPosition = worldPos;

方案2:射线检测获取精确交点(推荐)

透视相机下,不同深度的世界坐标不同,若需要触摸点与场景中物体/平面的精确交点,用射线检测更可靠:

if (Input.touchCount > 0)
{
    Touch touch = Input.touches[0];
    Ray ray = Camera.main.ScreenPointToRay(touch.position);
    
    // 示例:检测与y=0地面平面的交点
    Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
    float hitDistance;
    if (groundPlane.Raycast(ray, out hitDistance))
    {
        Vector3 worldPos = ray.GetPoint(hitDistance);
        Vector2 touchPosition = worldPos;
        // 此处使用获取到的世界坐标
    }

    // 若要检测场景中的碰撞体,替换为以下代码:
    /*
    if (Physics.Raycast(ray, out RaycastHit hitInfo))
    {
        Vector3 worldPos = hitInfo.point;
        Vector2 touchPosition = worldPos;
    }
    */
}

额外说明

  • 确保Camera.main已正确赋值(相机需挂载MainCamera标签)
  • 若使用2D物理,将Physics.Raycast替换为Physics2D.Raycast

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:35:35