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

Unity3D:点击按钮实现Cinemachine相机平滑旋转90度的方法

解决方案:用协程实现相机平滑旋转

你之前的问题核心是OnClick事件只触发一次函数调用,那段带Time.deltaTime的代码只执行了一帧,自然只能转极小角度。用协程可以让旋转逻辑在多帧内持续执行,完美实现平滑效果,且不需要额外补间库。

步骤1:添加控制变量

在相机脚本里定义几个关键变量,用来控制旋转时长和状态:

public Transform player;
public float rotateDuration = 1f; // 旋转90度的总时长,比如设为1秒
private bool isRotating = false; // 标记是否正在旋转,防止连续点击触发叠加

步骤2:修改按钮触发的函数

把原来的旋转函数改成协程的启动入口,同时增加状态判断:

public void CameraRotateL()
{
    if (!PauseMenu.isPaused && !isRotating)
    {
        StartCoroutine(RotateAroundPlayer(90f));
    }
}

public void CameraRotateR()
{
    if (!PauseMenu.isPaused && !isRotating)
    {
        StartCoroutine(RotateAroundPlayer(-90f));
    }
}

步骤3:编写旋转协程

核心逻辑放在协程里,逐帧计算旋转角度,直到完成目标旋转:

private IEnumerator RotateAroundPlayer(float targetAngle)
{
    isRotating = true;
    float elapsedTime = 0f;
    float rotatedAngle = 0f;

    while (elapsedTime < rotateDuration)
    {
        // 计算当前帧需要旋转的角度
        float frameAngle = (targetAngle / rotateDuration) * Time.deltaTime;
        transform.RotateAround(player.transform.position, Vector3.up, frameAngle);
        
        rotatedAngle += Mathf.Abs(frameAngle);
        elapsedTime += Time.deltaTime;
        yield return null; // 等待下一帧继续执行
    }

    // 修正帧时间波动带来的角度误差,确保最终刚好转够90度
    float remainingAngle = targetAngle - rotatedAngle * Mathf.Sign(targetAngle);
    if (Mathf.Abs(remainingAngle) > 0.1f)
    {
        transform.RotateAround(player.transform.position, Vector3.up, remainingAngle);
    }

    isRotating = false;
}

关键细节说明

  • isRotating变量用来避免用户连续点击按钮,导致多个旋转协程同时运行,出现混乱。
  • 协程的while循环会持续执行到旋转时长耗尽,每帧只转对应比例的角度,实现平滑过渡。
  • 最后的误差修正可以抵消帧时间不稳定带来的偏差,保证相机最终旋转角度精确到90度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:10:09