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

Unity通过相机Translate实现拖拽缩放功能异常问题求助

问题排查&修复方案


核心Bug原因

  • initialPosition是VerticalZooming方法内的局部变量,每次Update调用方法时都会被重置为Vector3.zero,跨帧无法保留按下鼠标时记录的初始值
  • 代码存在拼写错误:帧更新时写的是intialPosition = newPosition,少打了一个i,就算把变量改成全局也无法正常赋值更新
  • 逻辑不符合需求:按照设计只需要在鼠标按下时记录一次初始坐标,不需要每帧更新初始坐标,原有写法相当于每帧都把上一帧的坐标当成初始值,对比的是相邻两帧的y差,不是和按下时的初始值差
  • 缩放逻辑错误:Zoom方法里直接乘相机的z轴坐标,Unity透视相机默认朝z负方向,初始z值一般为负数,会直接导致缩放方向翻转

修正后代码

[Header("Vertical Zooming")]
[SerializeField] private float zoomSpeed = 10f;
[SerializeField] private float minZoomDistance = 2f; // 最小缩放距离,避免穿模
[SerializeField] private float maxZoomDistance = 10f; // 最大缩放距离,避免目标过小

// 改为全局变量,跨帧保留按下时的初始坐标
private Vector3 initialPressPosition;
// 自行替换为你的玩家对象引用
[SerializeField] private Transform playerTrans;

private void Update()
{
    VerticalZooming();
}

private void VerticalZooming()
{
    // 兼容移动端触摸输入
    if (Input.touchCount > 0)
    {
        Touch touch = Input.GetTouch(0);
        if (touch.phase == TouchPhase.Began)
        {
            initialPressPosition = mCamRef.ScreenToViewportPoint(touch.position);
        }
        else if (touch.phase == TouchPhase.Moved)
        {
            Vector3 currentPosition = mCamRef.ScreenToViewportPoint(touch.position);
            float yDiff = currentPosition.y - initialPressPosition.y;
            // 加0.01死区,避免微小抖动触发误缩放
            if (Mathf.Abs(yDiff) > 0.01f)
            {
                Zoom(yDiff * zoomSpeed * Time.deltaTime);
            }
        }
    }
    // 编辑器鼠标输入逻辑
    else
    {
        if (Input.GetMouseButtonDown(0))
        {
            initialPressPosition = mCamRef.ScreenToViewportPoint(Input.mousePosition);
        }

        if (Input.GetMouseButton(0))
        {
            Vector3 currentPosition = mCamRef.ScreenToViewportPoint(Input.mousePosition);
            float yDiff = currentPosition.y - initialPressPosition.y;
            if (Mathf.Abs(yDiff) > 0.01f)
            {
                Zoom(yDiff * zoomSpeed * Time.deltaTime);
            }
        }
    }
}

private void Zoom(float delta)
{
    // 限制缩放范围
    float currentDistance = Vector3.Distance(transform.position, playerTrans.position);
    if (currentDistance - delta < minZoomDistance || currentDistance - delta > maxZoomDistance)
    {
        return;
    }
    transform.Translate(transform.forward * delta, Space.World);
}

补充说明

如果需要实现“滑动距离对应缩放幅度”的效果而非累积缩放,直接用y轴差值计算相机目标位置即可,不需要每帧累加位移。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 02:15:03