Menu
CoddyTech

Kwaterniony

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

Quaternion to typ Unity reprezentujący obrót: transform.rotation jest jednym z nich, podobnie jak wartość zwracana przez Quaternion.Euler. Jego cztery liczby x, y, z i w nie są kątami i nigdy nie musisz ustawiać ich samodzielnie. Obrót wykonuje się przez mnożenie. Obrót pomnożony przez wektor obraca wektor:

Vector3 a = Quaternion.Euler(0, 90, 0) * Vector3.forward;       // (1, 0, 0)
Vector3 b = Quaternion.Euler(0, 0, 45) * new Vector3(2, 0, 0);  // (1.41, 1.41, 0)
Vector3 lamp = transform.position + transform.rotation * new Vector3(0, 1, 2);

Obrót umieszcza się po lewej stronie: Vector3.forward * transform.rotation nie skompiluje się. W trzecim wierszu przesunięcie jest obracane zgodnie z obrotem obiektu, więc lamp to punkt położony 1 jednostkę nad obiektem i 2 jednostki przed nim w jego własnych kierunkach, niezależnie od tego, w którą stronę jest zwrócony.

Obrót pomnożony przez obrót łączy oba obroty. transform.rotation * Quaternion.Euler(0, 90, 0) oznacza obrót obiektu, a następnie ćwierć obrotu wokół jego własnej osi y; po zamianie kolejności ćwierć obrotu następuje wokół osi y świata. W przypadku obiektu ustawionego pionowo oba dają ten sam wynik. W przypadku samolotu przechylonego o 30 stopni jest inaczej, ponieważ jego własna oś y również się przechyla:

Quaternion banked = Quaternion.Euler(0, 0, 30);
Quaternion own = banked * Quaternion.Euler(0, 90, 0);    // dziób (0.87, 0.5, 0): wznosi się podczas skrętu
Quaternion world = Quaternion.Euler(0, 90, 0) * banked;  // dziób (1, 0, 0): pozostaje na tym samym poziomie

Quaternion.identity oznacza brak obrotu — to właśnie tę wartość przekazujesz do Instantiate. Mnożenie przez nią niczego nie zmienia, a transform.rotation = Quaternion.identity; przywraca obiekt do pozycji bez obrotu.

challenge icon

Wyzwanie

Średni

Spraw, by spacja wystrzeliwała trzy pociski rozchodzące się wachlarzem, który obraca się wraz z działem.

  1. Zastąp linię Instantiate kodem for (int i = -1; i <= 1; i++).
  2. W niej ustaw Quaternion aim = transform.rotation * Quaternion.Euler(0, i * spread, 0);.
  3. Stwórz każdy pocisk 1 jednostkę dalej wzdłuż jego kierunku: Instantiate(bulletPrefab, transform.position + aim * Vector3.forward, aim);.

Naciśnij „Graj”, obracaj się i strzelaj: trzy pociski rozchodzą się wachlarzem, w odstępach co 20 stopni. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

using UnityEngine;

public class Gun : MonoBehaviour
{
    public GameObject bulletPrefab;
    public float turnSpeed = 90f;
    public float spread = 20f;

    void Update()
    {
        if (Input.GetKey(KeyCode.RightArrow)) transform.Rotate(0, turnSpeed * Time.deltaTime, 0);
        if (Input.GetKey(KeyCode.LeftArrow)) transform.Rotate(0, -turnSpeed * Time.deltaTime, 0);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            // Jeden pocisk, prosto przed siebie. Wystrzel trzy: pod kątem -spread, 0 i spread stopni.
            Instantiate(bulletPrefab, transform.position, transform.rotation);
        }
    }
}

Wszystkie lekcje w sekcji Fizyka i rozgrywka

Poćwicz samodzielnie: Edytor online Unity