Menu
CoddyTech

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

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 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

Задание

Средне

Пусть камера трясётся при нажатии пробела.

  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;.

Нажми «Играть», запусти игру и нажми пробел: изображение будет трястись, пока камера следует за игроком. Затем нажми «Проверить».

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

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