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.

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.


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.

¿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.

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.

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.


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.


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”