Menu
CoddyTech

Drgania kamery

Część sekcji Fizyka i rozgrywka ścieżki Unity w Coddy. Lekcja 50 z 71.

Wstrząs to krótka seria losowych przesunięć: przez kilka dziesiątych sekundy kamera znajduje się w losowym miejscu blisko swojej pozycji spoczynkowej, na każdej klatce w nowym, a potem wraca. Koroutyna się do tego nadaje, ponieważ działa przez kilka klatek i sama się kończy. Ta kamera trzęsie się, gdy głaz ląduje (inny skrypt wywołuje BoulderLanded(); plik zaczyna się od using System.Collections;, aby używać 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 to losowe przesunięcie o długości do strength w dowolnym kierunku, a yield return null wybiera nowe w następnej klatce. Dodawanie Time.deltaTime przy każdym przebiegu zlicza rzeczywiste sekundy, więc wstrząs trwa duration niezależnie od liczby klatek na sekundę. Ostatnia linia przywraca kamerę na miejsce; bez niej kamera pozostałaby tam, gdzie pozostawiło ją ostatnie przesunięcie.

Na każdej klatce Unity uruchamia wszystkie Update(), następnie korutyny oczekujące na yield return null, a potem wszystkie LateUpdate(). Dlatego kamera śledząca, która ustawia swoją pozycję w LateUpdate(), nadpisuje wszystko, co zrobił wstrząs. Wstrząsanie localPosition pozwala tego uniknąć, gdy kamera jest dzieckiem pustego obiektu, który ją śledzi: obiekt nadrzędny się porusza, a kamera trzęsie się wokół swojej pozycji względem niego.

challenge icon

Wyzwanie

Średni

Spraw, by poniższa kamera trzęsła się po naciśnięciu spacji.

  1. Dodaj pole Vector3 shake;, a w LateUpdate() ustaw transform.position = player.position + offset + shake;.
  2. W Shake(), dopóki elapsed < duration: shake = Random.insideUnitSphere * strength;, dodaj Time.deltaTime do elapsed, yield return null;.
  3. Po pętli ustaw shake = Vector3.zero;.

Naciśnij „Graj”, uruchom grę i naciśnij spację: widok będzie się trząść podczas podążania za graczem. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

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()
    {
        // Potrząsaj kamerą przez duration sekund, odchylając ją od pozycji śledzenia maksymalnie o strength.
        yield return null;
    }
}

Wszystkie lekcje w sekcji Fizyka i rozgrywka

Poćwicz samodzielnie: Edytor online Unity