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

获取3D平面世界空间中对应缩放的鼠标点击位置

解决3D平面鼠标点击位置映射(对应缩放)的方法

嘿,我完全懂你这会儿的困惑——明明知道用Input.mousePosition但它和3D平面本身不挂钩,还要对应平面缩放、相机还能随便动,确实容易绕进去。下面给你一步步拆解实现思路,代码都是Unity里直接能用的:

核心思路

我们需要把屏幕鼠标位置 → 世界空间射线 → 与3D平面的交点 → 转换为对应平面缩放的局部坐标,这一套流程走下来就能得到你要的Vector2。


步骤1:发射射线获取世界空间交点

首先得从相机发射射线,找到鼠标点击在3D平面上的世界坐标。这里分两种场景:

场景A:平面有碰撞体(比如MeshCollider)

如果你的3D平面是带碰撞体的物体(比如默认的Quad加了MeshCollider),用Physics.Raycast最直接:

public GameObject targetPlane; // 把你的3D平面拖到这里
private Camera mainCam;

void Start()
{
    mainCam = Camera.main;
}

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Ray ray = mainCam.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out RaycastHit hit))
        {
            // 确保点击的是目标平面
            if (hit.collider.gameObject == targetPlane)
            {
                Vector3 worldHitPoint = hit.point;
                // 拿到世界交点后,进入下一步转换
                Vector2 mappedPos = MapWorldPointToPlaneScale(worldHitPoint);
                Debug.Log("对应缩放的坐标:" + mappedPos);
            }
        }
    }
}

场景B:平面无碰撞体(纯数学平面)

如果不想用碰撞体,也可以用Plane类直接计算射线与平面的交点:

public Transform targetPlaneTransform; // 平面的Transform组件
private Camera mainCam;

void Start()
{
    mainCam = Camera.main;
}

void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Ray ray = mainCam.ScreenPointToRay(Input.mousePosition);
        // 用平面的法线(这里用transform.up,可根据平面朝向调整)和平面位置创建数学平面
        Plane plane = new Plane(targetPlaneTransform.up, targetPlaneTransform.position);
        
        if (plane.Raycast(ray, out float distance))
        {
            Vector3 worldHitPoint = ray.GetPoint(distance);
            Vector2 mappedPos = MapWorldPointToPlaneScale(worldHitPoint);
            Debug.Log("对应缩放的坐标:" + mappedPos);
        }
    }
}

步骤2:将世界交点转换为对应缩放的Vector2

这一步是关键,要把世界坐标转成平面的局部坐标,再对应到缩放比例。这里以默认的Unity Quad为例(默认Quad的局部坐标范围是(-0.5, -0.5, 0)到(0.5, 0.5, 0)):

private Vector2 MapWorldPointToPlaneScale(Vector3 worldPoint)
{
    // 1. 把世界坐标转成平面的局部坐标
    Vector3 localPoint = targetPlaneTransform.InverseTransformPoint(worldPoint);
    
    // 2. 把默认Quad的-0.5~0.5范围平移到0~1的区间
    localPoint += new Vector3(0.5f, 0.5f, 0f);
    
    // 3. 乘以平面的缩放值,得到对应缩放的坐标
    Vector2 result = new Vector2(
        localPoint.x * targetPlaneTransform.localScale.x,
        localPoint.y * targetPlaneTransform.localScale.y
    );
    
    // 如果你的平面是XZ朝向(比如地面),就把y换成z:
    // Vector2 result = new Vector2(localPoint.x * targetPlaneTransform.localScale.x, localPoint.z * targetPlaneTransform.localScale.z);
    
    return result;
}

调整说明

  • 如果你的3D平面不是默认Quad(比如自定义的平面,局部坐标范围是(0,0,0)到(1,1,0)),那可以跳过步骤2,直接用局部坐标乘以缩放就行。
  • 平面朝向不同时,记得切换对应的轴(比如地面用XZ轴,墙面用XY或YZ轴)。

验证示例

假设你的Quad缩放是(2, 3, 1):

  • 点击Quad的左下角(世界空间对应平面局部原点的位置),会返回(0, 0)
  • 点击Quad的右上角,会返回(2, 3)
  • 点击中心位置,会返回(1, 1.5)

完全符合你要的和缩放对应的效果,而且不管相机怎么移动旋转,只要射线能击中平面,结果都是准确的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 21:37:33