Menu
CoddyTech

Quaternioni

Fa parte della sezione Fisica e gameplay del percorso Unity di Coddy. Lezione 43 di 71.

Un Quaternion è il tipo di Unity per una rotazione: transform.rotation è una rotazione, così come il valore restituito da Quaternion.Euler. I suoi quattro numeri x, y, z e w non sono angoli e non devi mai impostarli tu. Per lavorare con le rotazioni, le moltiplichi. Una rotazione moltiplicata per un vettore lo ruota:

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

La rotazione va a sinistra: Vector3.forward * transform.rotation non viene compilato. La terza riga ruota uno spostamento in base alla rotazione dell'oggetto stesso, quindi lamp è il punto situato 1 unità sopra e 2 davanti all'oggetto, secondo le sue direzioni, qualunque sia il suo orientamento.

Una rotazione moltiplicata per un'altra rotazione combina le due rotazioni. transform.rotation * Quaternion.Euler(0, 90, 0) applica prima la rotazione dell'oggetto e poi un quarto di giro attorno al suo asse y proprio; invertendo l'ordine, il quarto di giro avviene attorno all'asse y del mondo. Per un oggetto dritto, i due risultati sono uguali. Per un aereo inclinato di 30 gradi, invece, sono diversi, perché il suo asse y si inclina insieme a esso:

Quaternion banked = Quaternion.Euler(0, 0, 30);
Quaternion own = banked * Quaternion.Euler(0, 90, 0);    // muso (0.87, 0.5, 0): sale mentre gira
Quaternion world = Quaternion.Euler(0, 90, 0) * banked;  // muso (1, 0, 0): resta alla stessa quota

Quaternion.identity rappresenta l'assenza totale di rotazione, quella che hai passato a Instantiate. Moltiplicare per essa non cambia nulla e transform.rotation = Quaternion.identity; riporta un oggetto alla sua posa senza rotazione.

challenge icon

Sfida

Medio

Fai in modo che la barra spaziatrice spari una rosa di tre proiettili che ruota insieme alla pistola.

  1. Sostituisci la riga Instantiate con for (int i = -1; i <= 1; i++).
  2. Al suo interno, imposta Quaternion aim = transform.rotation * Quaternion.Euler(0, i * spread, 0);.
  3. Genera ogni proiettile a 1 unità di distanza nella sua direzione: Instantiate(bulletPrefab, transform.position + aim * Vector3.forward, aim);.

Premi «Gioca», ruota e spara: i tre proiettili si allargano a ventaglio, a 20 gradi di distanza l'uno dall'altro. Poi premi «Verifica».

Provalo tu

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))
        {
            // Un proiettile, dritto davanti. Sparane tre: a -spread, 0 e spread gradi.
            Instantiate(bulletPrefab, transform.position, transform.rotation);
        }
    }
}

Tutte le lezioni di Fisica e gameplay

Esercitati da solo: Playground Unity