Menu
CoddyTech

Tremor da Câmera

Parte da seção Física e Jogabilidade do Journey de Unity da Coddy. Lição 50 de 71.

Um tremor é uma sequência curta de deslocamentos aleatórios: por alguns décimos de segundo, a câmera fica em uma posição aleatória perto da posição de repouso, uma nova a cada quadro, e então volta. Uma coroutine é adequada, porque é executada ao longo de vários quadros e termina sozinha. Esta câmera treme quando uma pedra cai (outro script chama BoulderLanded(); o arquivo começa com using System.Collections; para 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 é um deslocamento aleatório de até strength de comprimento em qualquer direção, e yield return null escolhe um novo no próximo quadro. Somar Time.deltaTime a cada iteração contabiliza segundos reais, então o tremor dura duration em qualquer taxa de quadros. A última linha coloca a câmera de volta na posição; sem ela, a câmera fica onde o último deslocamento a deixou.

A cada quadro, o Unity executa todos os Update(), depois as coroutines que estão aguardando yield return null, e então todos os LateUpdate(). Assim, uma câmera de acompanhamento que define sua posição em LateUpdate() sobrescreve o que o tremor fez. Tremer localPosition evita isso quando a câmera é filha de um objeto vazio que faz o acompanhamento: o objeto pai se move, e a câmera treme ao redor da posição que ocupa nele.

challenge icon

Desafio

Médio

Faça a câmera a seguir tremer ao pressionar Space.

  1. Adicione um campo Vector3 shake; e, em LateUpdate(), defina transform.position = player.position + offset + shake;.
  2. Em Shake(), enquanto elapsed < duration: shake = Random.insideUnitSphere * strength;, adicione Time.deltaTime a elapsed, yield return null;.
  3. Após o loop, defina shake = Vector3.zero;.

Pressione “Jogar”, execute e pressione Space: a visualização treme enquanto acompanha o jogador. Depois, clique em “Verificar”.

Experimente você mesmo

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()
    {
        // Balance a câmera por duration segundos, com deslocamento de até strength em relação à sua posição de acompanhamento.
        yield return null;
    }
}

Todas as lições de Física e Jogabilidade

Pratique por conta própria: Playground de Unity