Quaternions
Parte da seção Física e Jogabilidade do Journey de Unity da Coddy. Lição 43 de 71.
Um Quaternion é o tipo do Unity para uma rotação: transform.rotation é uma, assim como o valor retornado por Quaternion.Euler. Seus quatro números x, y, z e w não são ângulos, e você nunca precisa defini-los por conta própria. O que você faz com rotações é multiplicá-las. Uma rotação multiplicada por um vetor gira o vetor:
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);A rotação fica à esquerda: Vector3.forward * transform.rotation não compila. A terceira linha gira um deslocamento pela rotação do próprio objeto, então lamp é o ponto 1 unidade acima e 2 à frente do objeto em suas próprias direções, para qualquer lado que ele esteja voltado.
Uma rotação multiplicada por outra rotação combina os dois giros. transform.rotation * Quaternion.Euler(0, 90, 0) é a rotação do objeto seguida por um quarto de volta em torno do próprio eixo y; invertendo a ordem, o quarto de volta ocorre em torno do eixo y do mundo. Para um objeto na vertical, os dois casos dão o mesmo resultado. Para um avião inclinado em 30 graus, não, porque seu próprio eixo y fica inclinado junto com ele:
Quaternion banked = Quaternion.Euler(0, 0, 30);
Quaternion own = banked * Quaternion.Euler(0, 90, 0); // nariz (0.87, 0.5, 0): sobe ao virar
Quaternion world = Quaternion.Euler(0, 90, 0) * banked; // nariz (1, 0, 0): permanece niveladoQuaternion.identity significa que não há giro algum; é o valor que você passou para Instantiate. Multiplicar por ele não muda nada, e transform.rotation = Quaternion.identity; devolve um objeto à sua pose sem rotação.
Desafio
MédioFaça com que a barra de espaço dispare uma rajada de três projéteis que gira junto com a arma.
- Substitua a linha
Instantiateporfor (int i = -1; i <= 1; i++). - Nela, defina
Quaternion aim = transform.rotation * Quaternion.Euler(0, i * spread, 0);. - Gere cada projétil a 1 unidade de distância, na direção para a qual ele aponta:
Instantiate(bulletPrefab, transform.position + aim * Vector3.forward, aim);.
Pressione “Jogar”, gire e dispare: três projéteis se espalham, separados por 20 graus. Depois, pressione “Verificar”.
Experimente você mesmo
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))
{
// Uma bala, diretamente à frente. Dispare três: a -spread, 0 e spread graus.
Instantiate(bulletPrefab, transform.position, transform.rotation);
}
}
}
Todas as lições de Física e Jogabilidade
1Rigidbody
Gravidade e MassaEmpurrar com AddForcePular com um ImpulsoFixedUpdate para FísicaVelocidadeCorpos CinemáticosRevisão: Plataforma de Lançamento4Corrotinas
InvocarInvocar repetidamente, Cancelar invocaçãoSua primeira corrotinaLoops em corrotinasInterrompendo corrotinasRevisão: contagem regressiva10Projeto: Fuga da Arena
A ArenaCaçadores2Colisões
OnCollisionEnterO que eu acertei?Quebre no impactoNo chãoQuique e atritoFormas dos collidersRevisão: Parede destrutível5Projeto: Corrida das Moedas
A Bola RolanteMoedas para ColetarPratique por conta própria: Playground de Unity