Menu
CoddyTech

Тряска камеры

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 48 из 63.

Тряска — это короткая последовательность случайных смещений: в течение нескольких десятых секунды камера находится в случайной точке рядом с положением покоя, выбирая новую точку на каждом кадре, а затем возвращается обратно. Здесь подойдёт корутина, потому что она выполняется на протяжении нескольких кадров и завершается сама. Эта камера трясётся, когда падает валун (другой скрипт вызывает 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

Задание

Средне

Эта камера следует за игроком (стрелки перемещают игрока): в LateUpdate() она находится в позиции игрока плюс offset, и она не является дочерним объектом. Добавь тряску, которая работает, пока камера следует за игроком:

  • Пробел трясёт камеру в течение duration (0.4) секунды. На каждом кадре тряски камера находится в новой случайной точке на расстоянии до strength (0.3) от позиции следования, продолжая следовать за игроком.
  • Когда тряска заканчивается, камера возвращается точно в позицию следования.

Пробел уже запускает корутину Shake(). Нажми Play, побегай и нажми пробел, затем нажми Check.

Попробуйте сами

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;
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Физика и игровой процесс