ZoomedTransform
(这个答案是在一个相对变换的假设下运行的,而不是 31eee384 的答案所怀疑的相机的绝对位置。)
我认为您的代码存在一些问题。我将单独处理它们,以便它们更容易理解,但它们都与以下行有关:
CameraTransform.position = Vector3.Lerp (CameraTransform.position, CameraTransform.position + ZoomedTransform.position, 5f * Time.deltaTime);
首先,让我们看看您是如何使用Vector3.Lerp()
. 对于 的第三个参数Vector3.Lerp()
,您提供5f * Time.deltaTime
. 这个值到底有什么作用?好吧,标准帧速率约为 60 FPS,所以Time.deltaTime
= ~1/60。因此,5f * Time.deltaTime
= 5/60 = ~0.0833。
Vector3.Lerp()
但是,第三个论点的期望是什么?根据文档,第三个参数应该在 0 和 1 之间,并确定返回的参数Vector3
应该更接近第一个还是第二个给定的Vector3
。所以是的,5f * Time.deltaTime
落在这个范围内,但不会发生插值 - 因为它总是在 ~0.0833 左右,而不是从 0 到 1(或 1 到 0)。每一帧,你基本上总是回来cameraPos + zoomTransform * 0.0833
。
另一个值得注意的问题是您如何更新CameraTransform.position
每一帧的值,然后使用新的(增加的)值作为Vector3.Lerp()
下一帧的参数。(这有点像int i = i + 1;
循环。)这就是为什么你的相机飞过地图这么快的原因。这是每一帧发生的事情,使用Vector3.Lerp()
我之前计算的假设结果(伪代码):
// Frame 1
cameraPosFrame_1 = cameraPosFrame_0 + zoomTransform * 0.0833;
// Frame 2
cameraPosFrame_2 = cameraPosFrame_1 + zoomTransform * 0.0833;
// Frame 3
cameraPosFrame_3 = cameraPosFrame_2 + zoomTransform * 0.0833;
// etc...
每一帧,zoomTransform * 0.0833
都被添加到相机的位置。这最终会是一个非常非常快速且不间断的增值 - 所以你的相机会飞过地图。
解决这些问题的一种方法是使用变量来存储相机的初始本地位置、缩放进度和缩放速度。这样,我们就不会丢失相机的原始位置,并且我们可以跟踪变焦的进展情况以及何时停止变焦。
[RequireComponent(typeof(Camera))]
public class Zoom : MonoBehaviour {
private Transform CameraTransform = null;
public Transform ZoomedTransform;
private Vector3 startLocalPos;
private float zoomProgress = 0;
private float zoomLength = 2; // Number of seconds zoom will take
private bool zoomed = false;
void Start () {
CameraTransform = Camera.main.transform;
startLocalPos = CameraTransform.localPosition;
}
// Update is called once per frame
void Update () {
if (Input.GetKey (KeyCode.LeftShift))
{
zoomProgress += Time.deltaTime;
CameraTransform.localPosition = Vector3.Lerp (startLocalPos, startLocalPos + ZoomedTransform.position, zoomProgress / zoomLength);
CameraTransform.Rotate(ZoomedTransform.rotation.eulerAngles);
}
}
}
希望这可以帮助!如果您有任何问题,请告诉我。这个答案确实有点杂乱无章,所以我希望你能从中得到重点。