Menu
CoddyTech

Quaternionen

Teil des Abschnitts Physik und Gameplay der Unity-Journey von Coddy. Lektion 43 von 71.

Ein Quaternion ist in Unity der Typ für eine Drehung: transform.rotation ist ein solcher Wert, ebenso wie der Wert, den Quaternion.Euler zurückgibt. Seine vier Zahlen x, y, z und w sind keine Winkel, und du musst sie nie selbst festlegen. Mit Drehungen multiplizierst du. Eine Drehung mal einem Vektor dreht den Vektor:

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

Die Drehung steht links: Vector3.forward * transform.rotation lässt sich nicht kompilieren. Die dritte Zeile dreht einen Versatz um die eigene Drehung des Objekts. Daher ist lamp der Punkt, der in den eigenen Richtungen des Objekts 1 Einheit über und 2 Einheiten vor dem Objekt liegt, unabhängig davon, in welche Richtung es zeigt.

Eine Drehung mal einer Drehung kombiniert die beiden Drehungen. transform.rotation * Quaternion.Euler(0, 90, 0) bedeutet, dass auf die Drehung des Objekts eine Vierteldrehung um seine eigene y-Achse folgt; bei vertauschter Reihenfolge erfolgt die Vierteldrehung um die y-Achse der Welt. Bei einem aufrechten Objekt ergibt beides dasselbe. Bei einem um 30 Grad geneigten Flugzeug ist das nicht der Fall, weil seine eigene y-Achse mitgeneigt ist:

Quaternion banked = Quaternion.Euler(0, 0, 30);
Quaternion own = banked * Quaternion.Euler(0, 90, 0);    // Spitze (0.87, 0.5, 0): Sie steigt beim Drehen an
Quaternion world = Quaternion.Euler(0, 90, 0) * banked;  // Spitze (1, 0, 0): Sie bleibt waagerecht

Quaternion.identity bedeutet, dass gar keine Drehung stattfindet; genau diesen Wert hast du an Instantiate übergeben. Die Multiplikation damit ändert nichts, und transform.rotation = Quaternion.identity; bringt ein Objekt in seine ungedrehte Pose zurück.

challenge icon

Aufgabe

Mittel

Lass die Leertaste eine Streuung aus drei Geschossen abfeuern, die sich mit der Waffe dreht.

  1. Ersetze die Instantiate-Zeile durch for (int i = -1; i <= 1; i++).
  2. Setze darin Quaternion aim = transform.rotation * Quaternion.Euler(0, i * spread, 0);.
  3. Erzeuge jedes Geschoss 1 Einheit weit in seiner Flugrichtung: Instantiate(bulletPrefab, transform.position + aim * Vector3.forward, aim);.

Drücke „Spielen“, drehe dich und feuere: Drei Geschosse fächern sich auf, mit einem Abstand von 20 Grad. Drücke dann „Prüfen“.

Probier es selbst

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))
        {
            // Ein Projektil geradeaus. Feuere drei ab: bei -spread, 0 und spread Grad.
            Instantiate(bulletPrefab, transform.position, transform.rotation);
        }
    }
}

Alle Lektionen in Physik und Gameplay

Übe selbstständig: Unity-Playground