Hasta ahora hemos visto algunos árboles de comportamiento secuencial bastante simples.
Ahora vamos a agregar una condición que pruebe si algo es 'verdadero' o 'falso' antes de que el Árbol
de comportamiento continúe
ejecutándose y, por lo tanto, agregaremos un 'Nodo de decisión' dentro del código.
Vamos a hacer eso dentro de nuestro ataque,
pero antes que nada, necesitamos escribir nuestro método que tomará la decisión por nosotros.
Actualmente estamos atacando todo el tiempo. Realmente solo quieres que el bot ataque si realmente puede
ver al jugador
y en este caso, cuando comienzas, no puede porque el jugador está detrás de una pared.
Además, si el jugador está fuera de un rango visible, tampoco querrás que ataque.
Ahora, si recuerdas en la parte superior de este programa, hay un visibleRange y un shotRange configurado,
por lo que este visibleRange (que es 80) determinará si el jugador está dentro de las 80 unidades del
bot, entonces puede verlo . También probará al mismo tiempo si no hay un muro entre
el jugador y el bot, lo cual es una buena situación enemiga porque quieres que el bot sea consciente de que hay infraestructura a su alrededor.
Entonces, como el último método aquí debajo del Fuego, agregaré uno nuevo que usaremos en nuestro código de
Árbol de comportamiento.
Entonces se llama SeePlayer.
Es un booleano,
así que es como lo habíamos hecho antes, pero esta vez en realidad lo vamos a usar como una prueba lógica en
el Árbol de comportamiento.
Entonces, lo que está haciendo es calcular el vector desde el bot hasta
el reproductor y
luego también vamos a tener un RaycastHit.
Así que emitiremos rayos a lo largo de ese vector de distancia para ver si golpeamos algo y si golpeamos algo (que en este caso es un
muro), entonces obviamente no podemos ver al jugador porque hay un muro en el camino, así
que Tengo
un pequeño bool establecido aquí, diciendo 'seeWall = false' para empezar.
También estoy haciendo una depuración. DrawRay en el entorno, para que podamos ver dónde se
proyecta ese vector de distancia.
Esto es realmente bueno si estás tratando de depurar visualmente lo que está sucediendo y dónde están tus vectores.
Yo siempre uso esto.
Ahora va a proyectar un rayo, haz la física. Raycast como lo hemos hecho antes y luego ver si
hemos tocado algo llamado 'muro'.
Si es así, seeWall será igual a 'verdadero'.
Ahora, solo por un momento en Unity, si vas al Mapa y lo dejas caer, hay todos estos muros y cada uno ha
sido etiquetado con 'muro' y así es como funciona la Física. Raycast va a funcionar.
Ahora asegúrese de que su rayo que está proyectando realmente atraviese la pared (o cualquier objeto que esté tratando de
detectar como un obstáculo) y es por eso
que esta depuración. DrawRay es una gran idea.
Después de hacer eso, también estoy imprimiendo el valor de seeWall en algún código de depuración para el árbol de comportamiento en sí mismo para que pueda verlo
cuando trabaja a través de los diferentes nodos y lo que están haciendo, lo que
también es bastante útil.
Luego, finalmente, para determinar si podemos ver al jugador
o no, la prueba es: si la magnitud de esa distancia del vector de dirección entre los dos jugadores
es menor que el rango visible Y no hay muro en el camino. Esta vez, no nos preocupa si el bot está orientado en la dirección
correcta o no.
Así que imaginemos que tiene un pequeño sistema de radar a bordo y no necesita
mirar en una dirección para saber si el jugador está cerca. Ahora, si el jugador está en ese radio y no
hay un muro en el camino, entonces vamos a devolver "verdadero" que sí vemos al
jugador, de lo contrario, devolveremos un "falso".
Entonces este es el método para nuestro nuevo nodo.
Ok, entonces guardaremos eso y luego entraremos en el script de Ataque y lo que
haremos será agregar un nuevo nodo en nuestro árbol sobre la 'secuencia'. Así que aquí arriba,
ahora voy a agregar esto. Entonces, el código es 'while SeePlayer' Ahora este
nodo 'while' es un nodo de prueba especial y le permitirá ejecutar algo que sea un valor verdadero o falso
e incluso invertirlo
para verificar (no tiene que ser cierto ejecutar, también puede
ser falso) y no detendrá la ejecución de su árbol.
De acuerdo, incluso podría poner, por ejemplo, 'mientras no SeePlayer' si desea cambiar la lógica y lo haremos un poco más
tarde, pero no en este caso aquí.
Ahora este nodo 'while' solo puede tener 1 hijo.
Por lo tanto, debemos asegurarnos de haber sangrado todo esto de esa manera, de lo contrario, el sistema Behavior Tree
se quejará al respecto.
Entonces, la secuencia de disparos solo sucederá si el método SeePlayer nos da una 'verdadera' aquí.
Así que guardemos eso y probémoslo.
Entonces, de vuelta en Unity, haga clic en el Droid para verificar que el guión esté bien y obtendrá un texto rosado donde todo
está bien con el guión de ataque.
Ok, presionemos Play y echemos un vistazo a lo que obtenemos.
Entonces, en el árbol de comportamiento, mientras SeePlayer está sentado allí, wall = True, puedes ver eso allí.
También puedes ver en la escena que el rayo de depuración atraviesa y golpea la pared, lo que está causando
el 'muro = Verdadero' aquí y nos está haciendo para que no podamos ver al jugador.
Muevamos el reproductor a
la vista, así que si doy la vuelta a la esquina y listo. Tan pronto como veo y estoy dentro del alcance visual, el Droid comienza
a disparar y si me doy la
vuelta y regreso nuevamente, se detendrá tan pronto como haya un muro en el camino.
Si atravieso este muro porque no estoy limitado como jugador por
NavMesh, ya no puede verme. Si regreso, lo hará y, debido al código anterior, también se volverá hacia
el jugador, para disparar y se puede ver que el
Árbol de Comportamiento funciona bastante bien con ese poco de lógica. Entonces estás comenzando a ver el poder de los
árboles de comportamiento, que puedes crear un montón de métodos que hacen una sola acción para tu jugador
y luego puedes unirlos en el árbol de comportamiento, lo que hace que sea mucho más fácil para alguien quien
no está realmente familiarizado con el código pero
también hace su A. YO. bastante potente donde puedes mezclar y combinar diferentes comportamientos. Solo por intereses, volvamos
a Atacar y cambiemos ese código en la parte superior con la declaración while para que sea un 'no' y revertamos esa lógica,
de modo que cuando NO veamos al jugador, vamos a atacar al jugador, lo
que no tiene sentido lógico, pero lo que eso significa es que, si bien no estás a la vista del
robot con tu personaje, disparará en tu dirección.
Así que solo guarda eso. Mientras estoy
aquí, también debería mencionar esta declaración while debido a la programación
habitual, pensarás que mientras que la declaración significa 'bucle'. En el caso de Behavior Trees, no significa bucle.
Entonces esto NO es un bucle.
En todo caso, es una declaración if, si
quieres pensar en ella como algo, por lo que no hará que esto se
repita dentro de aquí y simplemente se llame 'while'. Bien, así que guarda eso. Volvamos y echemos un vistazo a cómo eso afecta nuestro Árbol de Comportamiento.
Entonces, presionemos Reproducir y esperaríamos que nos disparen de inmediato porque no podemos ver al
jugador.
Ahora, si me muevo hacia el rango, entonces no nos dispararán y, de hecho, toda la
secuencia deja de ejecutarse, por lo que ni siquiera vamos a girar y mirar
al jugador porque este bit aquí no se está cumpliendo, en la medida en que poder ver al jugador.
Correcto.
Así es como también puedes agregar algo de lógica.
Ahora no tiene que usar el 'while not' en este caso porque SeePlayer podría ser parte de la secuencia.
Si coloca SeePlayer en la secuencia (volvamos a aquí y saquemos eso de allí y
póngalo
aquí), entonces está legítimamente permitido fallar ...
y como se trata de una secuencia, el resto no se ejecutará de todos modos, así que guardemos y echemos
un vistazo.
Comprueba que está recargado aquí.
Ahora tenemos una secuencia. Si presionamos Reproducir ... ok, no podemos ver al jugador.
Entonces, la secuencia se ha detenido con el SeePlayer e intentemos acercarnos para ver qué sucede ...
disparará el SeePlayer y luego
el resto se ejecutará como antes.
Entonces, en este caso, la instrucción while no nos está ayudando con el SeePlayer porque tiene que ser cierto
para que se ejecute el resto del código.
Entonces, en este caso, lo que hemos hecho es girar el árbol sobre su cabeza en la medida en que
este SeePlayer ahora es un Nodo Hoja, mientras que antes era un Nodo Decorador porque tenía niños debajo y le permitía tomar
una decisión y la decisión en ese caso toma su decisión cuando se desea invertir el valor que
sale de ella.
Por lo tanto, "mientras no" va a ser mucho más común en este caso en particular, pero depende de lo que
intente hacer.
Entonces esa es
la secuencia y también agregar esa lógica. En el siguiente video, veremos los Nodos Selectores.