Hasta ahora, hemos creado un montón de pequeños árboles de comportamiento y ahora es el momento de juntarlos.
Si los dibujáramos en un diagrama, se verían así y lo
que está viendo en la pantalla es una representación cercana de hacia dónde nos dirigimos,
pero no está completo (de ninguna manera) porque no hay suficiente espacio en la
pantalla para hacerlo pero puedes ver las áreas clave. Puede ver todos los árboles clave que hemos creado hasta ahora
y todas las formas en que están interconectados.
La pregunta es: ¿cómo los juntas?
porque no son una 'secuencia' y no son algo de lo que deba seleccionarse. Lo que he hecho aquí es solo una
forma en que podría estructurarlos lógicamente y verá que hay un nuevo tipo de nodo
agregado en la parte superior llamado 'Paralelo'. Paralelo le permite correr 2 o más lados del árbol
a la vez (en este caso, son solo 2) y un lado se llama Patrulla y el otro lado se
llama Muerto.
El lado muerto está tomando el código que ya hemos escrito para el árbol muerto.
La Patrulla combina todos los comportamientos que el bot puede hacer cuando está vivo.
Queremos que los nodos bajo Patrol se ejecuten en un orden casi secuencial, de modo que cada Actualización, el bot verifique
si debe Huir, Atacar, Mirar a su alrededor o Vagar.
Comenzaremos yendo directamente a los bots
AI Behavior Tree, que combina todo lo que hemos hecho hasta ahora.
Entonces cree un nuevo script llamado 'BotAI. BT 'y en eso combinaremos todos los árboles.
No tiene que poner todos los árboles en un archivo, puede ponerlos en archivos separados y
adjuntarlos al Panda Behavior que se adjunta a su agente.
Sin embargo, me resulta mucho más fácil ver qué sucede cuando estamos depurando si están todos en
un solo archivo.
Así que así es como se verán.
En primer lugar, comenzamos con nuestro nodo de árbol 'Root'.
Aquí es donde el árbol comenzará a correr.
Luego tenemos nuestro nodo 'paralelo' que ejecutará a sus hijos al mismo tiempo y
puede ver que hay 1 árbol llamado Patrol que se ejecutará y 1 árbol llamado Dead.
Ya hemos escrito el muerto.
Estos están precedidos por un nodo 'repetir', un nodo 'mudo' y luego, por supuesto, el nodo 'árbol'. El nodo 'repetir' continuará repitiendo
(una y otra
vez) esta parte del árbol completo. 'mute' no le importa si el nodo debajo tiene éxito o falla,
simplemente sigue ejecutándolo.
Por lo tanto, dice "No escuche si tiene éxito o no", lo que permite que este
árbol
muerto aquí, cuando su agente no esté muerto, siga ejecutándose y siga verificando si el agente está muerto.
¿Qué hay en cada uno de estos árboles?
Verás que es una parte separada en el código para cada árbol, así que hay Patrulla ... y aquí está Attack y cada uno tiene su
nombre.
Ya no tienen la raíz en la parte superior.
Necesitan un nombre para poder encontrar cómo están todos unidos.
Ahora podría poner esto en un gran árbol grande sin todos estos pequeños subárboles, pero se
volvería un desastre y sería muy difícil de depurar. El árbol de patrulla tiene una secuencia y llamará al árbol 'Huir',
por lo que verificará si podemos huir.
Eso también continuará y dirá 'mientras nuestra salud no sea inferior a 40'
haremos nuestra pequeña
secuencia de Ataque, Mirada y Wander. Este es el código para el árbol de ataque, sacado directamente de nuestro pequeño
archivo que hicimos antes, para el ataque.
La única diferencia es que he cambiado Attack aquí, que tenía Root nuevamente en el archivo de Attack, si lo encuentro ...
está ahí, se puede ver y es lo mismo para todos los demás. Entonces Dead está aquí abajo.
Tenemos Flee, LookAround y luego Wander.
Entonces, una vez que lo tienes, puedes guardarlo y luego quieres ir a tu Droid y configurarlo como tu Árbol de
Comportamiento.
No necesitamos cambiar nada en el código de la clase AI en este momento porque no hemos creado
ningún método nuevo.
Su árbol, si tiene rosa y rojo todo el tiempo, significa que está todo listo, que ha encontrado
todos los métodos que necesita.
Ok, entonces presionemos Play y veamos qué sucede.
Correcto.
Si vamos al Inspector y echamos un vistazo, ambas cosas 'paralelas' se están ejecutando y el robot
en sí solo está sentado allí ... bajo patrulla. Ha disparado la 'Huida' y la Huida que
ha disparado está aquí abajo y dice 'mientras IsHealthLessThan (40. 0) ', por lo que no puede satisfacer este nodo y,
por lo tanto, no se ejecutará nada más. Aquí arriba, donde se llama a ese
Flee, está fallando ese árbol, por lo tanto, nada más está sucediendo porque una secuencia no
continuará cuando un nodo falla, por lo que inmediatamente tenemos un problema con nuestro árbol que no puede continuar e ir a
través de todos los procesos que el bot puede hacer cuando aún está vivo.
Ahora ha sucedido lo mismo con el árbol muerto, pero está bien porque nuestro bot no está muerto,
por lo que está atascado en este 'IsHealthLessThan (0. 1) 'que no es así, por lo que no va a explotar de inmediato.
Está
bien, está funcionando en paralelo aquí.
El problema está aquí abajo con el Huido, que queremos seguir adelante.
Entonces, si este árbol (para Huir) falla, todavía queremos que vaya y verifique los otros.
Así que deja de jugar y te presentaré un nuevo tipo de nodo. Regrese a su código de árbol bot. En Patrol, haremos 2
cambios. Donde hay 'secuencia'
aquí, vamos a llamar a eso 'respaldo' y a esta
otra 'secuencia' aquí, llamaremos a eso 'respaldo'.
Ahora el nodo de reserva es un nodo de secuencia pero permite que los nodos debajo de él fallen.
Entonces, a pesar de que fallan, seguirá adelante y seguirá ejecutando las cosas debajo de esto, así que esto es lo
que queremos usar en este caso porque Flee fallará cuando no tengamos que huir y cosas como Wander y LookAround, van
a fallar cuando estemos
dentro del alcance del jugador y en realidad los estamos atacando y el ataque va a
fallar cuando el jugador no
esté cerca, por lo que debemos permitirlo.
Así que guárdelo ahora y regresemos aquí y presione Reproducir nuevamente.
Ahora, cuando lo ejecutemos, descubrirá que el bot se moverá y responderá al código que le permite cambiar porque
estamos configurando nuestra alternativa: Ataque (que falla porque no puede atacar en el momento), entonces tiene
un árbol LookAround (que puede hacer y, por lo tanto, solo mira
a su alrededor).
Verás que el Wander no se está disparando en absoluto, no se está
bajando tanto y si miramos el LookAround (bajemos más) verás que dentro del LookAround, no
hay nada aquí que pueda
causar fallará mientras esté sano y lejos del jugador. Entonces, podemos forzarlo a fallar de vez en cuando,
de modo que permita una devolución de llamada, hasta el árbol de Patrulla que llamará a Wander, para
que LookAround pueda terminar. Realmente no tiene un estado terminado.
Supongo que eso es lo
que estoy diciendo y queremos que vuelva aquí, para que Wander pueda correr.
Así que
deja de jugar, abre tu
código nuevamente y en el LookAround, vamos a agregar otro nodo en esta secuencia.
Entonces, después de esperar una cantidad aleatoria de tiempo, pondremos otro 'aleatorio' aquí
y luego, como niños, pondremos 'Fail' y 'Succeed'. Por lo tanto, al azar, fallará o tendrá éxito, lo que lo arrojará de este árbol
al árbol de la Patrulla, donde se le permitirá pasar al Wander. Guarde eso y luego
presione Reproducir.
Todo bien.
Entonces el Droid ahora ha hecho un LookAround pero también ha activado un Wander, como viste que
sucedió allí y luego vuelve a LookAround ...
y cuando eso falla, vagará de nuevo y aquí puedes verlo estallar en un vagabundeo.
Ahora si tenemos suerte ...
sí,
a medida que pasa aquí, lo que sucedió es que el Ataque se ha activado y
eso se debe a que tiene un SeePlayer y un TargetPlayer y un LookAtTarget, que es lo que lo hizo girar
hacia el jugador y no quieres que
eso suceda a menos que sea en realidad en modo de ataque.
Ahora ha entrado aquí (nuevamente está en modo de ataque) y está comenzando a atacar a nuestro
lpayer porque lo encontró, lo cual es interesante en sí mismo, pero realmente no queremos que eso suceda, así
que tenemos que agregar algunas declaraciones condicionales más en nuestro árbol para que se comporte exactamente como queremos que lo haga.
Cuando el bot ve al jugador y va a atacarlo (o sabe que es capaz de
atacarlo), también debería poder moverse hacia el jugador, de modo que esté dentro del alcance y podamos modificar el guión de ataque para hacerlo.
Así que de vuelta en nuestro árbol
de comportamiento completo, vamos a reemplazar la secuencia de ataque que teníamos antes con algo un poco más complicado.
Así que déjame ponerlo, correcto, así que lo explicaré.
En primer lugar, vamos a verificar si podemos ver al
jugador en Ataque, antes
de continuar y luego, si podemos, comenzaremos una secuencia que hace TargetPlayer, LookAtPlayer. Entonces vamos a tener un
respaldo de 2 'ratos'.
El primero será
'mientras
ShotLinedUp' y luego 'mientras no ShotLinedUp'. Si un disparo está alineado, entonces la secuencia será 'Espera y dispara', que
teníamos antes, para disparar.
Si la toma NO está alineada, entonces queremos 'SetTargetDestination' y 'MoveToDestination'.
Por lo tanto, establecer el destino objetivo establecerá al jugador como ese objetivo particular.
Los 2 métodos nuevos que tenemos que escribir y agregar al script AI son
ShotLinedUp y SetTargetDestination.
Volvamos a esos scripts y, en la parte inferior, debajo de las otras tareas, agregaremos estos.
Entonces, el primero es SetTargetDestination.
Ya hemos establecido el objetivo en sí porque utilizamos (en nuestro script) TargetPlayer, que establece ese valor objetivo para que sea
igual a la posición del jugador.
Es por eso que solo estamos estableciendo un
destino objetivo aquí abajo y lo que está haciendo es decirle a nuestro NavMesh que ahora avance hacia el objetivo.
El siguiente es ShotLinedUp, que devuelve un 'verdadero' o 'falso' si
podemos dispararle al jugador.
Entonces, nuevamente, este es un problema de tipo de visibilidad en el que estamos probando la distancia dentro del valor
del rango de disparo (que se define en la parte superior) y que el ángulo entre el vector de avance de su agente
y el vector al objetivo es menor de 1 (un ángulo estrecho bastante pequeño).
Si ES, entonces podemos disparar.
Si NO es así, entonces nos moveremos y ajustaremos nuestra posición para acercarnos al jugador.
Entonces, guarde eso
y regresemos a Unity y presione Reproducir para ver cómo se desarrolla esto ahora.
El bot va a mirar alrededor y también vagar. Ahora, cuando pasa al jugador esta
vez, se da cuenta del jugador y se vuelve hacia él y viene a atacar.
Entonces, en lugar de ignorar por completo y salir y decir "No te vi", nos vio, así
que ahora podemos volver y comenzar a dispararle, en este punto, por lo
que su salud disminuirá.
Se va, va a desaparecer ...
encuentra un escondite ...
Ahora, si lo dejamos solo (no podemos verlo allí, ¿verdad?
Vamos a movernos.
Okay).
Cuando su salud supere los 40, volverá a hacer lo que estaba haciendo antes, que es mirar a
su alrededor y deambular y ahora no va a atacar a menos que nos encuentre de nuevo o nos acerquemos
e intentemos dispararle.
Todo el tiempo, su salud seguirá aumentando.
Ok, eso es Behavior Trees en pocas palabras.
Todavía hay mucho que aprender. Lo que sugeriría es que
ahora conoces tu camino, iría al comportamiento de los pandas. sitio web com, de donde proviene el complemento PandaBT y lee
la documentación porque es muy útil para ver qué nodos están disponibles, qué hacen y cómo
debe estructurarlos.
Además, descargue el complemento Panda Behavior completo de Asset Store porque tiene excelentes ejemplos que vienen con él y algunos
de ellos son realmente bastante complejos y le mostrarán cómo hacer algunas cosas
increíbles con Behavior Trees.