如何在 Unity 中创建超过 X 秒的 180 度相机轨道?
How to create a 180 degree camera orbit over X seconds in Unity?
我有一个围绕屏幕上的点旋转的相机。单击并左右拖动鼠标将围绕焦点旋转,松开鼠标将使相机离开该角度。
我正在尝试创建一个可以让相机平稳旋转 180 度的函数。因此,例如,如果摄像机在 "player" 后面并且调用了此函数,则摄像机将在 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 绘画图,以防我的解释令人困惑:
我不知道该怎么做。这听起来类似于使用 Vector3.Slerp
,但我找不到有效的解决方案。我离解决方案还很远,我真的没有任何合理的代码 post。我只想说到目前为止我已经尝试了两种方法:
1) 我试过使用 transform.RotateAround
,我传入的角度是 rotateSpeed * Time.deltaTime
。我的问题是我不知道如何检查结束条件,如果没有结束条件,我的相机将永远旋转。
2) 我试过弄乱 Quaternion.Slerp
,但看到的结果不是我预期的那样。
如何实现平滑的 180 度相机轨道,这需要预定的时间才能完成?
这是coroutine的教科书用途。基本上,启动一个跟踪轨道剩余时间的协程,然后根据剩余时间更新 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));
我有一个围绕屏幕上的点旋转的相机。单击并左右拖动鼠标将围绕焦点旋转,松开鼠标将使相机离开该角度。
我正在尝试创建一个可以让相机平稳旋转 180 度的函数。因此,例如,如果摄像机在 "player" 后面并且调用了此函数,则摄像机将在 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 绘画图,以防我的解释令人困惑:
我不知道该怎么做。这听起来类似于使用 Vector3.Slerp
,但我找不到有效的解决方案。我离解决方案还很远,我真的没有任何合理的代码 post。我只想说到目前为止我已经尝试了两种方法:
1) 我试过使用 transform.RotateAround
,我传入的角度是 rotateSpeed * Time.deltaTime
。我的问题是我不知道如何检查结束条件,如果没有结束条件,我的相机将永远旋转。
2) 我试过弄乱 Quaternion.Slerp
,但看到的结果不是我预期的那样。
如何实现平滑的 180 度相机轨道,这需要预定的时间才能完成?
这是coroutine的教科书用途。基本上,启动一个跟踪轨道剩余时间的协程,然后根据剩余时间更新 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));