Este es el segundo de dos tutoriales sobre cómo crear un script "Look At" en Unity 2022 para hacer que un objeto apunte hacia otro.


La versión en video de este tutorial no está disponible actualmente en este idioma.


Transcripción del video

¡Hola a todos!

Este es el segundo de dos tutoriales sobre cómo crear un script "Look At" en Unity 2022 para hacer que un objeto apunte hacia otro.

En concreto, en la primera parte analizamos el problema e implementamos una solución que implicaba una rotación instantánea del objeto. En este tutorial, en cambio, crearemos una rotación más lenta y gradual, utilizando Quaternions y Slerp.

En este tutorial asumiré que ya conoces conceptos como Time.deltaTime y el método Quaternion.Slerp, ya que los he explicado en otros tutoriales. Si no estás familiarizado con estos temas, te recomiendo revisar primero esos tutoriales.

En el tutorial anterior hablamos de los ejes globales y locales de la cámara, tanto para identificar el eje que indica su orientación como para señalar el eje alrededor del cual realizar las rotaciones.

Luego redujimos el problema al plano bidimensional y calculamos el ángulo de rotación alrededor del cual rotar el modelo 3D de la Surveillance Camera.

En nuestro script, este ángulo se llama deltaAngle y se mide en grados.

Para utilizar Slerp necesitamos tres cosas:

el quaternion que indica la orientación inicial;

el quaternion que indica la orientación objetivo que se debe alcanzar;

un método para indicar, en cada frame de la ejecución del juego, en qué punto nos encontramos, dentro de un rango entre 0 y 1, en la transición desde la orientación inicial hasta la final.

El primer punto es el más sencillo: la propiedad rotation de transform expresa la orientación del objeto en quaternions, por lo que para este campo utilizaremos transform.rotation.

El segundo punto tampoco es tan complicado: dada una orientación inicial expresada en quaternions, el quaternion que expresa la orientación objetivo obtenida al rotar la inicial se obtiene multiplicando la orientación inicial por la rotación que se debe realizar.

La rotación que se debe realizar, en nuestro script, es deltaAngle, que está expresado en grados. Sin embargo, necesitamos expresarlo como un Quaternion.

Afortunadamente, la función Euler de la clase Quaternion es justo lo que necesitamos: recibe tres parámetros, es decir, los ángulos de rotación alrededor de los ejes X, Y y Z, y devuelve un quaternion que representa esta transformación.

Como se mencionó antes, para obtener el quaternion objetivo debemos multiplicar el inicial por el de la rotación, por lo que en Update puedo escribir:

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

Justo después, puedo actualizar la orientación del objeto asignando a transform.rotation el quaternion calculado por Quaternion.Slerp, con:

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

Obviamente, ahora necesitamos definir evaluationTime: un valor float, entre 0 y 1, que representa el punto en el que nos encontramos en la transición desde la orientación inicial hasta la final.

Primero defino e inicializo esta variable escribiendo:

private float evaluationTime;

al inicio de la clase del script y:

evaluationTime = 0f;

dentro del método Start.

La variable evaluationTime debe incrementarse en cada frame, lo que puede hacerse escribiendo:

evaluationTime += Time.deltaTime;

justo después de la instrucción que contiene Slerp.

Esto es, por supuesto, solo un ejemplo. Mi consejo es multiplicar Time.deltaTime por una variable cuyo valor pueda ajustarse en tiempo real en el Inspector, hasta alcanzar una velocidad de rotación óptima. Hablé de este tema en mi tutorial sobre Time.deltaTime.

Sin embargo, de esta manera, en algún momento evaluationTime alcanzará 1.0, ya que se incrementa en cada frame del juego sin una opción de reinicio.

Pero, ¿cuándo debemos reiniciarlo?

La pregunta puede plantearse así: ¿cuándo estamos listos para comenzar una nueva rotación del modelo?

La respuesta es: cuando el modelo ya está apuntando al Player y está esperando a que se mueva.

Normalmente te diría que cuando el modelo de la Surveillance Camera apunta al Player y el Player permanece quieto, entonces deltaAngle es igual a 0, porque no hay rotación que realizar. Sin embargo, con valores float, especialmente en caso de conversiones entre diferentes unidades de medida, es mejor mantener cierto margen. Por lo tanto, diremos que la animación ha terminado, y que puede comenzar una nueva en cuanto el Player se mueva, cuando el valor absoluto de deltaAngle sea menor que 1f.

Así que, justo antes de la creación de targetRotation, dentro del método Update, escribo:

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

Luego coloco las tres instrucciones siguientes, es decir, la definición del quaternion objetivo, el cambio de orientación con Slerp y el incremento de evaluationTime, dentro del bloque else de esta instrucción if.

Guardo el script modificado, regreso al editor de Unity y presiono Play para observar el resultado. En este caso, la velocidad de rotación está determinada exclusivamente por Time.deltaTime y puede disminuirse o aumentarse, como se mencionó antes, multiplicando Time.deltaTime por una variable que se puede calibrar de forma interactiva.

Entonces, para recapitular: en este tutorial hemos visto cómo convertir el ángulo de rotación en Quaternions para calcular el Quaternion que representa la orientación objetivo, y luego utilizamos Slerp para realizar rotaciones más lentas, cuya velocidad también puede calibrarse manteniéndola independiente de la plataforma de ejecución, utilizando Time.deltaTime.

También definimos una condición de reinicio para Slerp, de modo que la rotación se reinicie cuando el Player esté quieto y listo para moverse nuevamente.

Bien, eso es todo por estos dos tutoriales. ¡Nos vemos pronto!

Este sitio web tiene como único propósito mostrar algunos de mis trabajos, sin ninguna intención promocional. Ten en cuenta que actualmente no estoy buscando - ni responderé a - solicitudes de trabajos personalizados, consultorías u otro tipo de colaboraciones profesionales.


POLÍTICA EXTENDIDA DE PRIVACIDAD Y UTILIZACIÓN DE COOKIES