首页 > 解决方案 > 如何在 Unity 中创建 X 秒内的 180 度相机轨道?

问题描述

我有一个绕屏幕上一个点旋转的相机。单击并左右拖动鼠标将围绕焦点旋转,释放鼠标将使相机保持在该角度。

我正在尝试创建一个功能,它将使相机平稳地旋转 180 度。例如,如果相机在“玩家”的后面并且这个函数被调用,相机将在 X 秒的过程中绕到玩家的前面,并停在与它开始的位置完全相反的位置。

这是我目前用于基于鼠标单击和拖动进行相机旋转的代码:

Quaternion camTurnAngle =
    Quaternion.AngleAxis(Input.GetAxis("Mouse X") * rotationSpeed, Vector3.up);

this.cameraOffset = camTurnAngle * this.cameraOffset;

Vector3 newPos = this.currentFocusPoint + this.cameraOffset;
transform.position = Vector3.Slerp(transform.position, newPos, smoothFactor);
transform.LookAt(this.currentFocusPoint);

我正在尝试用 UI 按钮(也称为单个函数调用)替换这个基于鼠标拖动的相机旋转,该按钮将在短时间内将相机完全旋转 180 度,然后如果再次按下它将旋转回来。这是一张 MS 油漆图,以防我的解释令人困惑:

在此处输入图像描述

我不确定如何处理这样的事情。这听起来类似于 using Vector3.Slerp,但我找不到有效的解决方案。我离解决方案还很远,以至于我真的没有任何明智的代码可以发布。我只想说到目前为止我已经尝试了两种方法:

1)我试过使用transform.RotateAround,我传入的角度是rotateSpeed * Time.deltaTime。我的问题是我不知道如何检查结束条件,没有一个我的相机将永远旋转。

2) 我试过弄乱Quaternion.Slerp,但看到的结果不是我所期望的。

我怎样才能实现平稳的 180 度相机轨道,这需要预定的时间才能完成?

标签: c#unity3dmathcamerarotation

解决方案


这是协程的教科书用法。基本上,启动一个协程来跟踪在轨道上剩余的时间,然后cameraOffset根据剩余的时间进行更新Time.deltaTime,或者更短的时间。

private IEnumerator RotateCam(float rotateDuration)
{
    float timeLeft = rotateDuration;

    // possibly - disable control of camera here

    while (timeLeft > 0)
    {
        yield return null;

        float elapsedRotationTime = Mathf.Min(timeLeft, Time.deltaTime);
        float angleThisFrame = 180f * elapsedRotationTime / rotateDuration;

        Quaternion camTurnAngle = Quaternion.AngleAxis(angleThisFrame, Vector3.up);

        this.cameraOffset = camTurnAngle * this.cameraOffset;
        transform.position = this.currentFocusPoint + this.cameraOffset;
        transform.LookAt(this.currentFocusPoint);

        timeLeft -= Time.deltaTime;
    }

    // possibly - re-enable control of camera here
}

然后,当您要开始旋转时:

// private Coroutine rotateCoroutine

this.rotateCoroutine = StartCoroutine(RotateCam(2f));

推荐阅读