
Unity 相机平滑缩放一般状况下有两种办法可以更改滑润值。可以运用按时间,运动发生在固定的持续时间内或者按速度,持续时间变化,但恒定的始终是运动速度。
当按速度平滑值,则一般情况下会涉及使用 MoveTowards 函数,该函数以一致的速率向目标增加值。例如下面的代码所示:
void ZoomCamera(float target)
{
cam.fieldOfView = Mathf.MoveTowards(cam.fieldOfView, target, zoomSpeed * Time.deltaTime);
}
然而,要在固定时间段内平滑运动,一般情况下会使用像 Lerp 这样的插值函数。但是,使用哪种方法都可以,因为这个特定动作,例如第一人称放大和缩小,基本上是玩家的运动,即将范围提高或降低到视线水平,平滑运动按速度就没有意义了。
假如移动是根据速度的,则较大的缩放量将比较小的缩放量花费更长的时间来过渡。相反,关于上面的代码示例,不管缩放多远,转换到缩放视图所需的时间都相同,那么这就更有意义了。

通过以上的说法,一般情况下会使用 Lerp。但是使用 Lerp 还是存在一点点问题的,虽然 Lerp 非常适合在固定时间段内更改值,但对于连续更改( 例如 following 值)就不太方便了。
那么这便是想要缩放功用做的事情,当然也希望缩放值平滑地跟随目标量,也想整个动作花费固定的时间。只是能够做的是运用 MoveTowards 办法,能够计算完整的运动所需的角度变化量,然后除以想要的持续时间,而不是通过固定速度,给一个速度值。例如下面的这段代码:
public class SmoothScopeZoom : MonoBehaviour
{
public Camera cam;
public float zoomMultiplier = 2;
public float defaultFov = 90;
public float zoomDuration = 2;
void Update()
{
if (Input.GetMouseButton(1))
{
ZoomCamera(defaultFov / zoomMultiplier);
}
else if (cam.fieldOfView != defaultFov)
{
ZoomCamera(defaultFov);
}
}
void ZoomCamera(float target)
{
float angle = Mathf.Abs((defaultFov / zoomMultiplier) - defaultFov);
cam.fieldOfView = Mathf.MoveTowards(cam.fieldOfView, target, angle / zoomDuration * Time.deltaTime);
}
}
以上的代码是不是会感觉有点疑惑?其中过渡的速度与所需的角度变化量有关,那么完全缩放移动的持续时间始终保持不变。在本例中为 1 秒,将结果除以想要的持续时间得到可以指定转换需要多长时间。
那么或许所希望的也是这样,当玩家在过渡途中使用缩放按钮,返回的默认视野所需的时间将减半。
虽然基于视野的缩放是制作逼真的缩放效果的好方法,但它最好用于模仿真实世界的基于镜头的缩放,例如使用范围,是吧。
但是,这可能也不是我们想要的缩放效果。例如,与其放大以查看远处的对象,可能真正想要做的只是将相机移近对象,那么此时3D天堂可能建议大家通过移动对象靠近来缩放对象了。