Menu
CoddyTech

Sacudida de cámara

Parte de la sección Física y jugabilidad del Journey de Unity de Coddy. Lección 50 de 71.

Un temblor es una serie breve de desplazamientos aleatorios: durante unas décimas de segundo, la cámara permanece en un punto aleatorio cerca de su posición de reposo, uno nuevo en cada fotograma, y después vuelve. Una corrutina es adecuada, porque se ejecuta a lo largo de varios fotogramas y termina por sí sola. Esta cámara tiembla cuando cae una roca (otro script llama a BoulderLanded(); el archivo empieza con 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 es un desplazamiento aleatorio de hasta strength de longitud en cualquier dirección, y yield return null elige uno nuevo en el siguiente fotograma. Sumar Time.deltaTime en cada iteración cuenta los segundos reales, así que el temblor dura duration con cualquier frecuencia de fotogramas. La última línea devuelve la cámara a su posición; sin ella, la cámara se queda donde la dejó el último desplazamiento.

En cada fotograma, Unity ejecuta todos los Update(), luego las corrutinas que esperan en yield return null y, después, todos los LateUpdate(). Por eso, una cámara de seguimiento que establece su posición en LateUpdate() sobrescribe lo que haya hecho el temblor. Sacudir localPosition evita esto cuando la cámara es hija de un objeto vacío que realiza el seguimiento: el objeto padre se mueve y la cámara tiembla alrededor de su posición dentro de él.

challenge icon

Desafío

Intermedio

Haz que la siguiente cámara tiemble al pulsar la barra espaciadora.

  1. Añade un campo Vector3 shake; y, en LateUpdate(), establece transform.position = player.position + offset + shake;.
  2. En Shake(), mientras elapsed < duration: shake = Random.insideUnitSphere * strength;, suma Time.deltaTime a elapsed y ejecuta yield return null;.
  3. Después del bucle, establece shake = Vector3.zero;.

Pulsa «Jugar», muévete y pulsa la barra espaciadora: la vista tiembla mientras sigue al jugador. Después, pulsa «Comprobar».

Pruébalo tú mismo

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()
    {
        // Sacude la cámara durante duration segundos, hasta una distancia de strength respecto a su posición de seguimiento.
        yield return null;
    }
}

Todas las lecciones de Física y jugabilidad

Practica por tu cuenta: Playground de Unity