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

Unity3D物体沿平面鼠标移动的缩放问题修复求助

Unity物体沿平面鼠标移动对齐问题修复

你当前代码的问题在于依赖鼠标按下时记录的固定mZCoord来转换屏幕坐标到世界坐标——当相机带角度或使用透视模式时,这个固定深度值会导致上下移动时的世界坐标计算出现缩放偏差,无法和鼠标位置准确对应。

改用射线检测平面交点的方案可以彻底解决这个问题,不管相机角度、投影模式如何,都能精准获取鼠标在目标平面上的对应位置。

修改后的完整代码

using UnityEngine;

public class PlaneMover : MonoBehaviour
{
    public Transform plane; // 在Inspector面板拖入目标平面
    private Vector3 mOffset;

    private void Update()
    {
        // 按住鼠标左键时移动物体
        if (Input.GetMouseButton(0))
        {
            transform.localPosition = GetMousePlaneIntersection() + mOffset;
        }
    }

    void OnMouseDown()
    {
        // 计算物体与鼠标平面交点的偏移量,避免点击瞬间物体跳位
        Vector3 mousePlanePoint = GetMousePlaneIntersection();
        mOffset = transform.localPosition - mousePlanePoint;
    }

    private Vector3 GetMousePlaneIntersection()
    {
        // 从相机向鼠标位置发射射线
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        // 定义目标平面:以平面的y高度为基准,法线向上(适配水平平面)
        Plane targetPlane = new Plane(Vector3.up, plane.position.y);

        if (targetPlane.Raycast(ray, out float distance))
        {
            // 返回射线与平面的交点,确保y轴始终固定在平面高度
            return ray.GetPoint(distance);
        }

        // 极端情况(射线未命中平面)下返回当前物体位置
        return transform.localPosition;
    }
}

关键修改说明

  • 移除了mZCoord变量,不再依赖固定深度值计算世界坐标
  • 用ScreenPointToRay发射射线,直接检测鼠标与目标平面的交点,从根源避免缩放偏差
  • 将物体移动逻辑从FixedUpdate改为Update,匹配鼠标输入的帧同步特性,移动更流畅
  • 通过Plane.Raycast确保物体y轴始终锁定在目标平面高度

注意事项

  • 必须在Inspector面板中把目标平面拖入plane变量
  • 如果你的平面不是水平的(比如垂直平面),只需修改Plane构造函数的法线参数(例如垂直平面用Vector3.forward)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 13:15:28