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

