Cuaterniones
Parte de la sección Física y jugabilidad del Journey de Unity de Coddy. Lección 43 de 71.
Un Quaternion es el tipo de Unity para una rotación: transform.rotation es uno, y también lo es lo que devuelve Quaternion.Euler. Sus cuatro números x, y, z y w no son ángulos, y nunca necesitas establecerlos tú mismo. Lo que haces con las rotaciones es multiplicar. Una rotación multiplicada por un vector gira el vector:
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 rotación va a la izquierda: Vector3.forward * transform.rotation no compila. La tercera línea gira un desplazamiento según la rotación propia del objeto, así que lamp es el punto situado 1 unidad por encima y 2 por delante del objeto, según sus propias direcciones, sea cual sea la orientación hacia la que mire.
Una rotación multiplicada por otra rotación combina ambos giros. transform.rotation * Quaternion.Euler(0, 90, 0) aplica la rotación del objeto y después un cuarto de giro alrededor de su propio eje y; si se invierte el orden, el cuarto de giro es alrededor del eje y del mundo. En un objeto vertical, ambos resultados son iguales. En un avión inclinado 30 grados, no lo son, porque su propio eje y se inclina con él:
Quaternion banked = Quaternion.Euler(0, 0, 30);
Quaternion own = banked * Quaternion.Euler(0, 90, 0); // morro (0.87, 0.5, 0): asciende al girar
Quaternion world = Quaternion.Euler(0, 90, 0) * banked; // morro (1, 0, 0): se mantiene niveladoQuaternion.identity representa no girar en absoluto; es el valor que has pasado a Instantiate. Multiplicar por él no cambia nada, y transform.rotation = Quaternion.identity; devuelve un objeto a su pose sin girar.
Desafío
IntermedioHaz que la barra espaciadora dispare una ráfaga de tres balas que giren con el arma.
- Reemplaza la línea
Instantiateporfor (int i = -1; i <= 1; i++). - Dentro, define
Quaternion aim = transform.rotation * Quaternion.Euler(0, i * spread, 0);. - Genera cada bala a 1 unidad de distancia en su dirección:
Instantiate(bulletPrefab, transform.position + aim * Vector3.forward, aim);.
Pulsa «Jugar», gira y dispara: las tres balas se abren en abanico, separadas por 20 grados. Después, pulsa «Comprobar».
Pruébalo tú mismo
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))
{
// Una bala, en línea recta hacia delante. Dispara tres: a -spread, 0 y spread grados.
Instantiate(bulletPrefab, transform.position, transform.rotation);
}
}
}
Todas las lecciones de Física y jugabilidad
1Cuerpo rígido
Gravedad y masaEmpujar con AddForceSaltar con un impulsoFixedUpdate para físicaVelocidadCuerpos cinemáticosRepaso: plataforma de lanzamiento4Corrutinas
InvocarInvokeRepeating y CancelInvokeTu primera corrutinaBucles en corrutinasDetener corrutinasRepaso: cuenta regresiva10Proyecto: Escape de la arena
La arenaCazadores2Colisiones
OnCollisionEnter¿Qué golpeé?Romper al impactarDe pie sobre el sueloRebote y fricciónFormas de los collidersRepaso: muro destructible5Proyecto: Carrera de Monedas
La pelota rodanteMonedas para recoger3Disparadores
Colisionadores de tipo triggerOnTriggerEnterObjetos coleccionablesLas cajas guardan el restoZonas letalesEntrada y salidaRepaso: llave y puertaPractica por tu cuenta: Playground de Unity