Posición relativa y seguimiento

Uno de los conceptos mas vitales a la hora de implementar una inteligencia artificial de movimiento es el de posición relativa o sentido de ubicación propia. En este caso analizaremos uno de los patrones mas básicos, saber si el objetivo esta hacia la derecha, izquierda, frente o atrás del objeto protagonista. Hay varias maneras complicadas de obtener este dato, pero siempre es bueno no intentar reinventar la rueda, así que vamos a usar una de las funciones integradas en Unity llamada InverseTransformPoint. Esta función toma un punto de espacio global y lo expresa en relación al espacio de la transformación en contexto. En otras palabras, usando esta función, podemos operar vectores como si nuestro cuerpo de referencia estuviera situado en el Vector 3 origen.

vectormath2
Inverse transform nos permite obtener el vector de posición de un objeto como si el origen fuera la transform inicial.

La ventaja de expresar ese vector de esa manera es que podemos aplicar lógica muy simple para saber la posición relativa. Como el vector esta expresado según la transform de la entidad original, podemos decir que si el componente x de este nuevo vector es mayor a cero entonces el objetivo esta hacia la derecha de nuestra entidad, mientras que si el componente z es mayor a cero sabemos que el objetivo esta hacia adelante. Por ende, podemos aplicar un script que detecte la posición relativa de un objetivo.

2017-09-02 19_00_15-UnityLab - Microsoft Visual Studio
Mientras que exista un objetivo asignado, siempre vamos a saber si está a la derecha, izquierda, adelante o atrás de la entidad que ejecute este comportamiento.
relativePos
El cubo azul siempre sabe la posición relativa de su objetivo.

Hagamos un misil teledirigido

Podemos inventar varias formas de lograr esto, en este caso vamos a ver 3 opciones:

  • Seguimiento directo
  • Interpolación esférica
  • Posición relativa

Podríamos perfectamente usar Lerp como explique en el post sobre Suavizado de cámara, pero vamos a poner una regla especifica: El misil siempre se mueve hacia adelante.

2017-09-02 17_37_45-UnityLab - Microsoft Visual Studio

2017-09-02 17_38_01-UnityLab - Microsoft Visual Studio
La regla para este ejercicio es forzar al misil a trabajar con este esqueleto, puede girar y moverse hacia adelante.

¿Por qué esta regla?

Siguiendo esta regla sabemos que un misil que tenga que tener sentido designado (es decir, que no sea simplemente una esfera, sino que tenga lados definidos) se comporte como esperamos, podemos forzar la posición y desentendernos del asunto, pero si trabajamos con la dirección y que siempre avanza hacia adelante vamos a poder cubrir todos los casos.

Caso 1: Seguimiento Directo

Este es el caso más simple, la transform de Unity nos provee con una función muy útil llama LookAt(Vector3), la cual orienta la transformacion para que el frente de la misma quede apuntando hacia el objetivo. Si aplicamos este comportamiento en la función Turn(), sabemos que el misil siempre va a estar mirando al objetivo.

2017-09-02 17_38_21-UnityLab - Microsoft Visual Studio

directHoming
El efecto producido por el seguimiento directo.

Simple y al punto, por desgracia esta solución no es para nada sutil y no respeta el sentido del cubo azul.

Caso 2: Interpolación Esférica

La interpolación esférica es similar a su contraparte lineal, el Lerp, con la excepción de que la interpolación esférica interpola en un arco entre dos puntos y no en una recta. SLerp es muy útil cuando se trabaja con ciclos de día y noche y con movimientos de puertas o cualquier cosa que tenga bisagras/pivotee.

2017-09-02 17_39_51-UnityLab - Microsoft Visual Studio
Nuevamente usamos la función LookAt, pero en este caso vamos a mirar a la interpolación esférica en un arco formado entre la dirección del misil y la posición del objetivo.

Un detalle importante que vale aclarar es porque se usa this.transform.position + this.transform.forward? que es exactamente ese forward? Vector3.forward es el vector especifico (0, 0, 1), mientras que transform.forward es el vector adelante de la transformación expresado como si la transformación fuera el origen, básicamente es la dirección de la transformación en el origen.

Todos los Vector3 del tipo up, forward, etc, están normalizados, siempre tienen módulo 1.

vectormath1
En este diagrama se puede ver porque se obtiene esa suma de dirección + posición.
directLerp
Comportamiento de la dirección por interpolación esférica.

El efecto logrado con este método es interesante, funciona en las 3 dimensiones y se ve bien. Sin embargo, requiere bastante modificación para que se vea mejor, por ejemplo, en el gif le agregue un retraso de medio segundo para que se active la dirección, de otra manera se veía muy extraño. También para evitar que fallen el objetivo se puede hacer que el factor de interpolación vaya aumentando a medida que la distancia va bajando.

Caso 3: Posición Relativa

El problema con los dos casos anteriores es lo adaptables que son, ambos casos fuerzan una dirección específica, pero cuando tenemos un juego guiado por física, estar cambiando direcciones y posiciones directo en la transform no es la mejor opción. Cuando trabajamos con física usamos fuerzas y torques sobre el cuerpo físico. También aplica esto cuando no es un misil ¿qué pasa si es un personaje que tiene que respetar ciertas reglas de movimiento? Ahí es donde entra este último caso. Para este caso vamos a usar lo primero que escribí en este artículo, la posición relativa. Podemos reaccionar acorde a si nuestro objetivo está a la derecha o a la izquierda.

 

 

2017-09-02 17_38_53-UnityLab - Microsoft Visual Studio
En este caso, según el signo de la coordenada x vamos a devolver un factor que va a definir si el misil gira a la derecha o a la izquierda.
homingCurve
Efecto generado por esta solución.

Lo bueno de implementar esta solución es que abre la posibilidad a aplicar muchas cosas que en los otros casos no es tan simple de hacer (o si es, pero se termina acudiendo a esto). Por ejemplo, que si el objetivo este atrás, el misil no pueda seguir rastreándolo, o en el ejemplo del Marauders Arena, todos los autos controlados por AI usan este método para saber si tienen que virar a la izquierda o derecha para seguir el camino asignado.

2 comentarios sobre “Posición relativa y seguimiento

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s