La forma más sencilla de crear un NPC que tome decisiones sobre qué hacer, en función de
la ubicación del jugador es Line Of Sight.
Line Of Sight funciona calculando el ángulo y la distancia desde el NPC al jugador
y utilizando estos datos para decidir qué acción tomar.
Es una forma muy fácil de crear un agente puramente reactivo cuyo comportamiento está determinado por si pueden o
no ver al jugador.
Para implementar esto, el NPC tiene un campo de visión.
Este es un cono que se extiende desde la ubicación del NPC en su dirección hacia adelante, por la longitud de su rango
visible y se extiende a través de un ángulo de visión. Para determinar si un jugador cae dentro
de este cono, calculamos el vector del NPC al jugador.
Luego determinamos si la 'distancia al jugador' es menor que el 'rango visible' y si el 'ángulo de la
posición del jugador' es menor que la del 'ángulo de visión'. Si ambas condiciones son verdaderas, el jugador es visible
para el NPC.
Sigue mientras te muestro cómo configurar este tipo de NPC de Line Of Sight. Descargue AIRobotGuard. paquete de unidad que viene
con esta conferencia.
Cree un nuevo proyecto de Unity 3D y arrastre y suelte ese archivo de paquete en sus Activos.
Cuando lo haga, obtendrá estos 2 artículos. Obtendrá una escena llamada RobotGuard (que puede abrir y verá
el guardia del robot parado en la escena) y obtendrá una carpeta de su obra de arte.
Los otros elementos los vas a agregar.
Entonces, una vez que tenga eso listo, agregaremos un controlador en primera persona, para que
podamos caminar y probar nuestra proximidad al NPC.
Vaya a 'Activos> Paquete de importación' y traiga el paquete 'Personajes'. Ese es el de
primera persona, tercera persona, etc. cosas en él, así que traiga todos esos
elementos y eso le dará una carpeta de Activos Estándar en
la que encontrará Personajes y luego queremos la primera persona 'Prefabs' y el FPSController.
Así que agárrate a eso,
arrástralo a la escena y solo levántalo para que quede por encima del suelo.
Ahora, una vez que hayas hecho eso, tendrá su propia cámara.
Entonces, la cámara que está en la escena, puede eliminarla (o simplemente apagarla).
Ahora para probar que esto está funcionando, solo presiona Play y deberías poder pasear por el entorno ...
como eso.
Okay.
Presione la tecla Esc para recuperar el mouse y dejar de jugar.
Okay.
Así que de vuelta en Activos, vamos a crear un script AIController.
Ya tengo uno aquí, pero desea 'Crear> C # Script' y llamarlo AIController. Dentro de ese script,
agregará esto.
Así que este es el script básico para que nuestra Línea de visión funcione.
En primer lugar, necesitamos saber dónde está el jugador, por lo que vamos a tener una transformación pública
en la parte superior para pasar por el jugador.
A continuación tenemos un montón de variables sobre el comportamiento del propio NPC.
Así que tenemos la 'velocidad de rotación' y la 'velocidad' habituales para girar y mover al personaje y luego tenemos nuestros valores de Línea
de visión.
Entonces, tenemos una distancia visible (así que esto es qué tan lejos del personaje puede detectar al jugador,
en este caso es 20), el
ángulo visible se establece en 30 (para que pueda verte a una distancia de 20, dentro de un ángulo de 30 grados a cada lado de
la misma.
Entonces este ángulo es como la mitad del campo de visión completo, que sería 60).
Luego tenemos una distancia de disparo y la distancia de disparo es qué tan cerca debe estar el personaje para
comenzar a disparar.
Entonces, si no está lo suficientemente cerca y lo ha detectado, puede correr hacia usted hasta que esté lo suficientemente cerca
como para tomar una foto.
A continuación, vamos a almacenar un estado y este estado nos ayudará a determinar qué animaciones
ejecutar un poco más adelante. Por lo tanto, el NPC tendrá 3 estados, tendrá IDLE, tendrá RUNNING y tendrá
DISPARO y los verá entrar en juego en la Actualización.
Ahora en la actualización es donde está sucediendo todo el trabajo.
Lo primero que hacemos es calcular la dirección del NPC al jugador. Ok, así que recuerda, hacer eso es el NPC
quitado de la posición del jugador y eso te dará tu vector de dirección.
Luego calculamos el ángulo entre ese vector de dirección y el vector orientado hacia adelante del NPC y podemos hacerlo
con nuestro Vector3. Método de ángulo
Entonces eso nos da un ángulo en grados.
Después de eso, haremos una declaración if para probar si la longitud de ese vector de dirección
está dentro de nuestro rango visible y nuestro ángulo es menor que nuestro ángulo visible, entonces estamos listos para comenzar.
Después de eso, estoy configurando los vectores de dirección 'y' a 0.
Entonces el vector de dirección estará en 3 dimensiones.
Si tu personaje es más alto o más bajo que el robot, entonces tener un valor y diferente hará que se incline y si no quieres
que se incline hacia arriba o hacia abajo para mirar a tu personaje, quieres que permanezca conectado
a tierra con su y -eje siempre mirando
directamente hacia arriba, entonces es una buena idea establecer este cambio en la 'y' siempre de nuevo a 0 después de haber realizado el cálculo.
Confía en mí, solo mantendrá todo en horizontal.
Luego establecemos la rotación del NPC con un slerp (como lo hemos hecho en el pasado) para que se mueva gradualmente hacia el vector de
dirección usando nuestra nuestra velocidad de rotación.
Entonces, con este código, si el jugador está dentro del rango visible del NPC, siempre estará girando hacia él.
Entonces solo tenemos que decidir si vamos a empujar al NPC hacia adelante, hacia el jugador.
Entonces
aquí abajo, después
de eso, tenemos 'if (dirección. magnitud> shootDist) ', lo que significa que
estamos fuera del alcance para disparar, pero todavía estamos dentro del alcance para correr detrás del personaje (porque esto está
dentro de esta declaración if aquí), así que
si no podemos disparar, entonces vamos a correr hacia el jugador, de lo contrario
vamos a disparar y, por lo tanto,
estamos estableciendo este valor de "estado".
Si el jugador está fuera de nuestro rango, entonces solo establecemos el estado en IDLE con este 'else' aquí,
así que asegúrese de tener esta declaración if correcta, de
lo contrario, esto le saldrá mal.
Luego, después de eso (y fuera
de esta declaración if-else, tenemos un 'if (state == "RUNNING")' y luego empuja el carácter hacia adelante, en esta línea aquí.
Por lo tanto, esta es la única vez que desea Traducir el carácter, cuando está en
el estado EN EJECUCIÓN, de lo contrario, está parado (INACTIVO) o DISPARANDO.
Bien, así que guárdelo, regrese a Unity y vamos
a agregar ese código (arrástrelo y suéltelo en su robot), seleccione el robot,
busque dónde está el código y dónde está expuesto 'Player', arrastre- y suelte su
FPSController allí, entonces el A. YO. lo sabe
Todo bien.
Probemos esto.
Presiona Play y si miramos alrededor y encontramos el robot ...
ahi esta.
Ahora sus animaciones no van a funcionar en este punto.
Solo queremos comprobar, si nos alejamos, observemos
cómo nos está siguiendo.
Este es él persiguiéndonos y
cuando se acerque lo suficiente, se detendrá y luego
entrará en el tiroteo y, si giramos, también seguirá girando hacia nosotros.
Por lo tanto, debería haber un punto (si podemos salir de su rango) en
el que él realmente
dejará de moverse por completo, lo que está por ahí y luego, si nos mantenemos fuera del rango y caminamos detrás de él (fuera
de su ángulo visible) deberíamos estar capaz de escabullirse desde un lado y no nos detectará.
Entonces no nos está detectando porque no se está volviendo hacia nosotros, pero si nos movemos dentro del alcance (salgamos aquí) allí, nos detectará, se volvió hacia nosotros
y comenzó a moverse dentro del alcance de tiro de nosotros.
Ok, esa es la lógica básica de esta línea de visión.
Ahora que la lógica de la Línea de visión está ahí, podemos agregar animaciones.
Ahora el robot que te he dado tiene animaciones y está listo para funcionar.
Si hace clic en el robot, encontrará que tiene un Animador en el Inspector.
Si hace doble clic en RobotGuard, se abrirá la ventana de Animator y podrá ver qué
hay allí.
Es muy sencillo.
Está configurado de manera muy similar a las cosas que hemos usado antes y básicamente son los
estados de animación,
'inactivo', 'correr' y 'disparar' y todos están vinculados por transiciones y disparadores en esas transiciones.
Así que los configuré, hay un 'isRunning' y un 'isShooting'
y un 'isIdle' y todos se vinculan entre estos estados de animación.
Entonces, no hay nada que tengas que hacer para esto, en cuanto a configurarlo, pero lo que
vamos a hacer es activarlos en el código en función del estado en el que se encuentra el NPC. Solo por interés, este modelo de robot en particular vino
con un proyecto de Unity hace muchos, muchos años y ni siquiera puedo
recordar qué versión era.
Quizás alguno de ustedes pueda recordar. Tal vez fue la versión 2 o algo
así porque estas animaciones eran animaciones heredadas, así que las actualicé para el sistema mecanim.
Volvamos al código, volvamos a nuestra escena allí ... Activos y abrir el código.
Lo primero que debemos hacer (como siempre) es agarrar a su animador.
Así que lo configuramos en la parte superior y luego en el Inicio, lo agarramos, así que 'anim = this. GetComponent 'para el Animador, así y
luego tenemos que
establecer los desencadenantes junto con cada estado.
Entonces, en la Actualización, vayamos a la primera para EJECUTAR.
Ahora aquí, podemos poner 'anim. SetTrigger ("isRunning"); ' - recuerde deletrear sus disparadores y capitalizar exactamente de la
misma manera que están configurados en los parámetros en el Animador.
Ahora eso configurará el disparador para que la animación 'isRunning' funcione.
El único problema al hacerlo de esta manera es que, si el personaje ya se está ejecutando, se volverá a disparar y se volverá a
disparar y se volverá a
disparar y puede terminar con cosas extrañas que suceden con múltiples disparadores que se disparan.
Entonces podemos probar ... 'if (estado! = "RUNNING") ', configuraremos el estado en RUNNING y configuraremos el
activador en' isRunning '.
Esto dice que si no está ejecutando, comience a ejecutar
y si ya está ejecutando, no hay necesidad de comenzar a ejecutar nuevamente.
Lo mismo para todos estos otros, así que haremos lo mismo con el disparo. Entonces es 'if
(estado! = "SHOOTING") ','
state = "SHOOTING"; y 'anim. SetTrigger ("isShooting"); '
y una vez más, por inactivo.
Así que ahora esto configurará nuestras animaciones en función del estado y garantizará que no se configuren
dos veces seguidas y luego justo en la parte inferior,
afuera, si las estamos ejecutando, todavía realizaremos nuestro empuje
hacia adelante Traducción.
Muy bien, así
que guárdelo y regresemos y probémoslo.
Entonces, presione Play ... va a comenzar a disparar (lo cual se debe a que estamos
justo a su lado) y ahora, si nos salimos del rango de
tiro, correrá detrás de nosotros y luego comenzará a disparar (voy a hacer que mi ventana de juego sea un poco más grande) y si logro
salir del rango, perderá interés y volverá a su estado inactivo
que puedes ver
allí y deberíamos poder ...
sigilosamente y porque no estamos dentro de ese rango, él no nos
está notando y puedo dar la vuelta ... regrese al alcance y comenzará a
dispararnos y perseguirnos y si giramos mientras estamos dentro del alcance, él girará.
Entonces eso es muy
simple A. YO. Mecánica llamada Line Of Sight, para que tu NPC persiga al jugador según
un rango de visibilidad.