Este é o segundo de dois tutoriais sobre como criar um script "Look At" no Unity 2022 para fazer um objeto apontar para outro.


A versão em vídeo deste tutorial não está disponível atualmente neste idioma.


Transcrição do vídeo

Olá a todos!

Este é o segundo de dois tutoriais sobre como criar um script "Look At" no Unity 2022 para fazer um objeto apontar para outro.

Especificamente, na primeira parte analisamos o problema e implementamos uma solução que envolvia uma rotação instantânea do objeto. Neste tutorial, porém, criaremos uma rotação mais lenta e gradual, utilizando Quaternions e Slerp.

Neste tutorial, vou assumir que você já está familiarizado com conceitos como Time.deltaTime e o método Quaternion.Slerp, pois já os abordei em outros tutoriais. Caso não esteja familiarizado com esses tópicos, recomendo que consulte esses tutoriais primeiro.

No tutorial anterior, discutimos os eixos globais e locais da câmera, tanto para identificar o eixo que indica sua orientação quanto para indicar o eixo em torno do qual realizar as rotações.

Em seguida, reduzimos o problema ao plano bidimensional e calculamos o ângulo de rotação em torno do qual girar o modelo 3D da Surveillance Camera.

Em nosso script, esse ângulo é chamado deltaAngle e é medido em graus.

Para usar Slerp, precisamos de três elementos:

o quaternion que indica a orientação inicial;

o quaternion que indica a orientação final a ser alcançada;

um método para indicar, a cada frame da execução do jogo, em que ponto estamos, em um intervalo de 0 a 1, na transição da orientação inicial para a final.

O primeiro ponto é o mais simples: a propriedade rotation de transform expressa a orientação do objeto em quaternions, então para esse campo utilizaremos transform.rotation.

O segundo ponto também não é tão complicado: dada uma orientação inicial expressa em quaternions, o quaternion que representa a orientação final obtida ao rotacionar a inicial é dado pelo produto da orientação inicial pela rotação a ser realizada.

A rotação a ser realizada, em nosso script, é deltaAngle, que está expressa em graus. Precisamos, porém, que ela esteja expressa como um Quaternion.

Felizmente, a função Euler da classe Quaternion é exatamente o que precisamos: ela recebe três parâmetros, ou seja, os ângulos de rotação em torno dos eixos X, Y e Z, e retorna um quaternion que representa essa transformação.

Como mencionado anteriormente, para obter o quaternion de destino precisamos multiplicar o inicial pelo da rotação, então no Update posso escrever:

Quaternion targetRotation = (transform.rotation * (Quaternion.Euler(0f, 0f, deltaAngle)));

Logo em seguida, posso atualizar a orientação do objeto atribuindo a transform.rotation o quaternion calculado por Quaternion.Slerp, com:

transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, evaluationTime);

Obviamente, agora precisamos definir evaluationTime: um valor float entre 0 e 1 que representa o ponto em que estamos na transição da orientação inicial para a final.

Primeiro, declaro e inicializo essa variável escrevendo:

private float evaluationTime;

no início da classe do script e:

evaluationTime = 0f;

dentro do método Start.

A variável evaluationTime deve então ser incrementada a cada frame, o que pode ser feito escrevendo:

evaluationTime += Time.deltaTime;

logo após a instrução que contém Slerp.

Este é, naturalmente, apenas um exemplo. Meu conselho é multiplicar Time.deltaTime por uma variável cujo valor possa ser ajustado em tempo real no Inspector, até alcançar uma velocidade de rotação ideal. Abordei esse tema no meu tutorial sobre Time.deltaTime.

No entanto, dessa forma, em algum momento evaluationTime chegará a 1.0, pois é incrementada a cada frame do jogo sem uma opção de reset.

Mas quando devemos redefini-la?

A pergunta pode ser feita da seguinte forma: quando estamos prontos para iniciar uma nova rotação do modelo?

A resposta é: quando o modelo já está apontando para o Player, aguardando que ele se mova.

Normalmente eu diria que quando o modelo da Surveillance Camera está apontando para o Player e o Player permanece parado, então deltaAngle é igual a 0, pois não há rotação a ser realizada. No entanto, com valores float, especialmente em casos de conversão entre diferentes unidades de medida, é melhor manter uma certa margem. Portanto, diremos que a animação terminou, e uma nova pode começar assim que o Player se mover, quando o valor absoluto de deltaAngle for menor que 1f.

Assim, logo antes da criação de targetRotation, dentro do método Update, escrevo:

if(Mathf.Abs(deltaAngle) < 1f) evaluationTime = 0f;

em seguida, coloco as três instruções seguintes, ou seja, a definição do quaternion de destino, a mudança de orientação com Slerp e o incremento de evaluationTime, dentro do bloco else dessa instrução if.

Salvo o script modificado, retorno ao editor do Unity e pressiono Play para observar o resultado. Nesse caso, a velocidade de rotação é determinada exclusivamente por Time.deltaTime e pode ser reduzida ou aumentada, como mencionado anteriormente, multiplicando Time.deltaTime por uma variável a ser calibrada interativamente.

Então, recapitulando: neste tutorial vimos como converter o ângulo de rotação em Quaternions para calcular o Quaternion que representa a orientação de destino e, em seguida, utilizamos Slerp para realizar rotações mais lentas, cuja velocidade também pode ser calibrada mantendo-a independente da plataforma de execução, usando Time.deltaTime.

Também definimos uma condição de reset para o Slerp, de modo que a rotação seja reiniciada quando o Player estiver parado e pronto para se mover novamente.

Ok, isso é tudo para estes dois tutoriais! Até breve!

Este site tem como único objetivo apresentar alguns dos meus trabalhos, sem qualquer finalidade promocional. Observe que, no momento, não estou procurando - nem responderei a - solicitações de trabalhos personalizados, consultorias ou qualquer outro tipo de colaboração profissional.


INFORMAÇÕES DE POLÍTICA DE PRIVACIDADE AVANÇADAS E USO DOS FICHEIROS DE COOKIES