Menu
CoddyTech

摄像机抖动

本课属于 Coddy Unity 学习旅程的“物理与游戏玩法”单元。第 50 课,共 71 课。

抖动是一小段随机偏移:在十分之几秒内,相机每帧都会停在静止位置附近的一个随机点,然后回到原位。协程很适合,因为它会跨多帧运行,并自行结束。当巨石落地时,这个相机就会抖动(另一个脚本会调用 BoulderLanded();文件以 using System.Collections; 开头,以使用 IEnumerator):

public float strength = 0.2f;
public float duration = 0.4f;
Vector3 rest;

void Start()
{
    rest = transform.localPosition;
}

public void BoulderLanded()
{
    StartCoroutine(Shake());
}

IEnumerator Shake()
{
    float elapsed = 0f;
    while (elapsed < duration)
    {
        transform.localPosition = rest + Random.insideUnitSphere * strength;
        elapsed += Time.deltaTime;
        yield return null;
    }
    transform.localPosition = rest;
}

Random.insideUnitSphere * strength 会在任意方向上产生一个长度不超过 strength 的随机偏移,而 yield return null 会在下一帧选取新的偏移。每次循环都加上 Time.deltaTime,就能累计实际经过的秒数,因此无论帧率如何,抖动都会持续 duration。最后一行会让相机回到原位;没有这一行,相机就会停留在最后一次偏移的位置。

每一帧中,Unity 会先运行每个 Update(),然后运行等待 yield return null 的协程,最后运行每个 LateUpdate()。因此,在 LateUpdate() 中设置位置的跟随相机会覆盖抖动造成的任何变化。如果相机是一个负责跟随的空对象的子对象,那么抖动 localPosition 就能避免这个问题:父对象移动,而相机则围绕它下方的位置抖动。

challenge icon

挑战

中等

按下 Space 时,让下面的摄像机抖动。

  1. 添加字段 Vector3 shake;,并在 LateUpdate() 中设置 transform.position = player.position + offset + shake;。
  2. 在 Shake() 中,当 elapsed < duration 时:shake = Random.insideUnitSphere * strength;,将 Time.deltaTime 加到 elapsed 上,然后执行 yield return null;。
  3. 循环结束后,设置 shake = Vector3.zero;。

按下“开始”,运行并按下 Space:视角会在跟随时抖动。然后点击“检查”。

亲手试试

using System.Collections;
using UnityEngine;

public class ShakeFollow : MonoBehaviour
{
    public Transform player;
    public Vector3 offset = new Vector3(0, 4, -8);
    public float strength = 0.3f;
    public float duration = 0.4f;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Shake());
        }
    }

    void LateUpdate()
    {
        transform.position = player.position + offset;
    }

    IEnumerator Shake()
    {
        // 让摄像机以跟随位置为基准抖动 duration 秒,最大偏移量为 strength。
        yield return null;
    }
}

物理与游戏玩法中的所有课

自己练习: Unity 在线编辑器