Está en la página 1de 98

Unidad 4.

x juego AI
aprender programacin y aplicar juego AI en Unity3D con un montn de proyectos de mu
estra y tcnicas de ltima generacin para su uso en el Unity3D proyectos
Aung Kyaw Sithu Clifford Peters Thet Naing Swe
Birmingham - Mumbai

Unity 4.x juego AI Programacin


Editorial Packt Copyright 2013
Todos los derechos reservados. Ninguna parte de este libro puede ser reproducida
, almacenada en un sistema de recuperacin, o transmitida de ninguna forma ni por
ningn medio, sin el permiso previo por escrito del editor, excepto en el caso de
citas breves incrustado en artculos crticos o comentarios.
Se ha hecho todo lo posible en la preparacin de este libro para asegurar la exact
itud de la informacin presentada. Sin embargo, la informacin contenida en este lib
ro se vende sin garanta, ya sea expresa o implcita. Ni los autores ni Packt Publis
hing, y sus concesionarios y distribuidores sern responsables por los daos y perju
icios causados o supuestamente causados directa o indirectamente por este libro.
Editorial Packt ha procurado proporcionar informacin acerca de todas las marcas d
e las compaas y productos mencionados en este libro por el uso apropiado de las ca
pitales.
Sin embargo, Editorial Packt no garantiza la exactitud de esta informacin.
Primera publicacin: julio de 2013 la
produccin de referencia: 1160713
Publicado por Packt Publishing Ltd.
Livery Lugar 35 Livery Street Birmingham B3 2PB, Reino Unido.
ISBN 978-1-84969-340-0
www.packtpub.com
Imagen de cubierta por Artie Ng (Artherng@yahoo.com.au)

Crditos
autores
Aung Kyaw Sithu Clifford Peters Thet Naing Swe
Revisores
Julien Lange Clifford Peters
Adquisicin Pandey Kartikey Editor
Editor tcnico de plomo
Arun Nadar
editores tcnicos Shashank Desai
Krishnaveni Haridas
Rikita Poojari
coordinador del proyecto Anurag Banerjee
correctores Maria Gould Paul Hindle Aaron Nash
indizador
Monica Mehta
grficos Ajmera
Ronak Dhruv Abhinash Sahu
coordinador de produccin
cubierta Mohite Nilesh R.
R. Mohite Nilesh trabajo
Sobre los autores
Aung Kyaw Sithu es originaria de Myanmar (Birmania) y tiene ms de 7 aos de experie
ncia en la industria del software. Sus intereses principales incluyen el juego d
e programacin, startups, entrepreneurship, escribir y compartir conocimientos. Po
see una licenciatura en Ciencias de la Universidad Tecnolgica de Nanyang (NTU), S
ingapur, especializndose en la tecnologa de medios digitales. En los ltimos aos, ha
trabajado como programador de Investigacin en INSEAD, Sor Game Studios Playware p
rogramador en Asia, Singapur y, por ltimo, como investigador asociado de la NTU.
En 2011, Aung co-fund Borde Rival Pte Ltd., con sede en Singapur, empresa de medi
os digitales interactivos que brinda un servicio de asesora tcnica a las agencias
creativas y tambin produce juegos mviles sociales. Visite http://rivaledge.sg para
ms informacin. Aung es el co-autor de Irrlicht 1.7 Motor 3D en tiempo real en la
gua del principiante, Packt Publishing, y tambin es profesor visitante de la NTU l
a realizacin de talleres sobre diseo y desarrollo de juegos con Unity3D.l puede ser
seguida en Twitter @aungsithu y mediante su LinkedIn proile linkedin.com/in/aun
gsithu.
Gracias a mis co-autores que trabajaron conmigo muy duro en este libro a pesar d
e sus apretadas agendas y consegu este libro publicado.
Adems, gracias al equipo de Editorial Packt para ayudarnos en la produccin de este
libro. Originalmente y, gracias a los increbles chicos de Unity3D para la constr
uccin de esta impresionante conjunto de herramientas y para hacerla accesible a l
os desarrolladores de juegos indie.

Clifford Peters es un programador y un equipo cientfico. l ha examinado los siguie


ntes libros de Editorial Packt: Unidad de Desarrollo de juegos Essentials, Unida
d de Desarrollo de juegos 3D, por ejemplo, la gua del principiante, Unidad 3 Desa
rrollo del juego Hotshot, Unity 3.x el Desarrollo de juegos por ejemplo Gua para
principiantes, la Unidad de Desarrollo de juegos de iOS Beginner's Guide, y Unit
y iOS Essentials.
Thet Naing Swe es el co-fundador y Director Creativo de borde Rival Pte Ltd., co
n sede en Singapur. Se gradu de la Universidad de Lancashire Central donde se esp
ecializ en el diseo del juego y el desarrollo y empez su carrera como programador d
el juego en el Reino Unido el cdigo basado en estudios de monos. Se traslad a Sing
apur en 2010 y trabaj como programador de grficos en la Universidad Tecnolgica de N
anyang (NTU) en un proyecto de investigacin cinematogrfica junto con Aung. Actualm
ente en el borde Rival, l es responsable de proyectos de consultora de medios digi
tales interactivos utilizando principalmente Unity3D, as como los juegos mviles pa
ra una audiencia informal. l puede ser alcanzado a travs de Thetnswe@rivaledge.sg.
Me gustara agradecer a todo el equipo de Editorial Packt para mantener un seguimi
ento de toda la logstica y asegurndose de que el libro fue publicado. Realmente ap
recio eso. Aparte de eso, me gustara dar las gracias a mis padres para elevar y a
poyar a m todos estos aos y dejarme perseguir mi sueo para convertirse en un desarr
ollador de juegos. Sin todo su apoyo, yo no estara aqu hoy.
Y originalmente, muchsimas gracias a mi esposa, Mayo Thandar Aung, que me permite
trabajar en este libro despus de ofice horas, tarde por la noche y los fines de
semana. Sin su apoyo y comprensin, este libro habra sido retrasado durante otro ao.
Estoy agradecido por tener tu apoyo con conmigo lo que hago. Te amo.

Sobre el revisor
Julien Lange es un experto de 32 aos en ingeniera de software. Comenz a desarrollar
se en Amstrad CPC464 con el lenguaje bsico cuando tena 7 aos. Aprendi pronto despus d
e Visual Basic, VB.NET y C#. Durante varios aos, hasta el final de sus estudios,
ha desarrollado y mantenido varios PHP y ASP.NET sitios web de comercio electrnic
o. Despus de su graduacin, continu para aprender ms y ms acerca de como la arquitectu
ra de software, gestin de proyectos siempre adquiriendo nuevas habilidades.
Fue en el trabajo mientras hablaba con un colega en agosto de 2009 y despus de de
scubrir el gran potencial de iPhone juegos y softwares que l decidi ind un motor d
e juego mejorado le permite centrarse slo en el objetivo principal de desarrollar
un juego y no un motor de juego. Despus de probar otros dos motores de juego, su
eleccin fue Unity 3D gracias a su compatibilidad con C# y su rendimiento de alta
frecuencia en el iPhone. Adems de su trabajo principal, abri iXGaming.com como au
tnomos en diciembre de 2010 y lanz varias aplicaciones en la AppStore, tales como
TV de dibujos animados, la galaxia, y as sucesivamente.
Me gustara agradecer a mi esposa para que me permita dedicar algn tiempo a revisar
los libros en mi equipo. Tambin me gustara dar las gracias a Federico por todo el
trabajo que hemos llevado a cabo junto con la unidad. Tambin me gustara agradecer
a todos la unidad actual almacn de activos de los clientes que estn utilizando mi
publicada activos y scripts. Los nuevos servicios estn llegando muy pronto en la
tienda de activos.
Por ltimo, quisiera agradecer a mi familia, mis amigos y compaeros, incluidos Step
hane D., Chakib L., Christelle P., D. Rafael, Alain D.L, Sebastien P., y Emmanue
l.

Apoyo www.PacktPub.com iles, eBooks, ofertas de descuento y ms


conveniente para visitar www.PacktPub.com para apoyar iles y descargas relaciona
das con tu libro.
Saba usted que Packt ofrece versiones eBook de cada libro publicado, con PDF y ePu
b iles disponibles? Puede actualizar a la versin de eBook en www.PacktPub.com y c
omo un libro de impresin cliente, usted tiene derecho a un descuento en el eBook
copiar. Pngase en contacto con nosotros en Service@packtpub.com para ms detalles.
En www.PacktPub.com, tambin puede leer una coleccin de artculos tcnicos, registrarse
para una variedad de boletines de novedades gratis y recibir descuentos y ofert
as exclusivas en Packt libros y libros electrnicos.
TM
http://PacktLib.PacktPub.com
necesita soluciones inmediatas a sus preguntas? Es PacktLib Packt's online biblio
teca digital de libros. Aqu, usted puede acceder, leer y buscar en Packt toda la
biblioteca de libros.
Por qu suscribirse?
plenamente consultables a travs de cada libro publicado por Packt Copiar y pegar,
impresin y marcar contenido On Demand y accesible mediante un navegador web de
libre acceso para Packt titulares de cuenta
si usted tiene una cuenta con Packt atwww.PacktPub.com, puede utilizar esto para
acceder a PacktLib hoy y ver nueve libros enteramente libre. Simplemente utilic
e sus credenciales de inicio de sesin para el acceso inmediato.

A la amorosa memoria de mi padre, U Aung Than, y a mi nia, que trae una nueva per
spectiva a mi vida
-dedicado por Aung Kyaw Sithu
Tabla de Contenidos
Prefacio 1 Captulo 1: Introduccin a la
inteligencia Artiicial AI 5 (AI) 5 AI en juegos 6 ai 7 tcnicas de las mquinas de e
stado finito (FSM) 7 al azar y probabilidad en AI 9 El sistema del sensor 10
Mesas 10 El sistema de mensajera 10
acudiendo, enjambre y pastoreo, Ruta 11 y siguientes 12 direccin A* pathinding 13
una malla de navegacin 20 el comportamiento de rboles 23 locomocin 25 algoritmo de
Dijkstra 28 Resumen 28
Captulo 2: mquinas de estado finito 29
El depsito del jugador 30 de la inicializacin de la clase 30 PlayerTankController
31
disparos bullet 32 controlando el 32
El tanque bullet clase 35 Configuracin de waypoints 37 abstracto FSM clase 38

El tanque enemigo AI 39 La patrulla estado 42 El Estado Chase 43 El ataque estad


o 44 los muertos 45 estado
teniendo daos 46
usando una FSM 47 el marco AdvanceFSM clase La clase FSMState 48 49 50
Las clases del estado PatrolState clase 50
la clase NPCTankController 52 Resumen 54
Captulo 3: el azar y la Probabilidad
aleatoria 55 56 56 clase Random
aleatorio simple juego de dados 57
Deinition de probabilidad 58 independientes y eventos relacionados 59 probabilid
ad condicional 59
dados cargados de 60
personalidades de carcter 61 FSM con probabilidad 62 Dynamic AI 64 Demo slot mach
ine 65 mquina de ranura aleatoria 65 probabilidad ponderada 69
cerca Miss 73
Resumen 74
Captulo 4: Implementacin de 75 sensores de
sistemas sensoriales bsicos 76 Escena 76 Configuracin del Reproductor y del aspect
o del tanque depsito de jugador 78 79 81 AI carcter de aspecto 81 83 83 Touch Sens
e perspectiva 86 88 88 Resumen de pruebas
[ II ]

Captulo 5: Flocado 89
desplazando desde la unidad's Island Demo 89 Comportamiento Individual 90 Contro
ller 97 implementacin alternativa 99 FlockController Resumen 101 106
Captulo 6: la ruta siguiente y comportamientos de direccin 107
tras una ruta 108 Ruta 110 Ruta 111 script seguidor evitando obstculos 114 aadiend
o una capa personalizada 116 eludir obstculos 117 Resumen 121
Captulo 7:* 123 Pathinding
algoritmo A* revisar 123 Aplicacin 124 Nodo 125 126 127 GridManager PriorityQueue
AStar 132 TestCode clase 135 Configuracin de escena 137 Prueba Resumen 141 142
Captulo 8: Malla de navegacin 143
Introduccin 144 Configuracin del mapa de navegacin 144 145 esttica hornear la malla
de navegacin Nav 145 Agente de malla 146
destinos de los agentes actualizar 148
escena con pendiente 149 NavMeshLayers 151 Off Enlaces de malla 153 generados fu
era de malla 154 Enlaces Manual fuera de enlaces de malla 156 Resumen 158
[ iii ]

Captulo 9: Comportamiento rboles 159


comportarse plugin 160 161 164 accin del flujo de trabajo interactuando con el sc
ript 166 169 Decorador comportarse depurador secuencia 171 172 Explorar comporta
n resultados 173 Selector selector de prioridad 175 177 179 181 de referencia pa
ralelos Los robots Versus Aliens proyecto 181 Resumen 184
Captulo 10: Juntando Todo 185
Configuracin de escena 186 etiquetas y capas de 188 189 vehculos coche reproductor
Controlador Controlador de Automvil AI 190 192 mquinas de estado finito (FSMs) 19
4
Estado de patrulla 195 Chase estado estado 198
armas de ataque 197 199 200 Gun Bullet 201 Lanzador de Misiles 203 205 208
ndice Resumen 209
[ ] iv

Prefacio
Este libro est pensado para ayudarle a incorporar diversas tcnicas de inteligencia
Artiicial en tus juegos. Vamos a discutir la adopcin de tcnicas tales como mquinas
de estado finito y el comportamiento de los rboles. Tambin veremos la circulacin,
superacin de obstculos, y su bloqueo. Tambin mostramos cmo seguir un camino, cmo crea
r un trazado utilizando el algoritmo A* pathinding y, a continuacin, cmo llegar a
un destino utilizando una malla de navegacin. Como un bono entraremos en detalle
acerca de azar y probabilidad y, a continuacin, incorporar estas ideas en un ltimo
proyecto.
Lo que este libro cubre el
Captulo 1, Introduccin a la inteligencia artificial, inteligencia Artiicial habla
acerca de lo que es y cmo se utiliza en los juegos. Adems, hablamos de diversas tcn
icas utilizadas para aplicar la inteligencia artificial en los juegos.
El captulo 2, mquinas de estado finito, describe una manera de simplificar la form
a en que gestionamos las decisiones, que AI tiene que hacer. Utilizamos FSMs par
a determinar cmo se comporta de AI en un estado en particular, y cmo las transicio
nes a otros estados.
Captulo 3, Azar y Probabilidad, analiza los conceptos bsicos detrs de la probabilid
ad, y cmo cambiar la probabilidad de un resultado concreto. A continuacin, veremos
cmo aadir aleatoriedad a nuestro juego para que el AI menos predecible.
Captulo 4, Aplicacin de sensores, mira donde debemos hacer nuestro personaje, cons
cientes del mundo que les rodea. Con la habilidad de nuestros personajes para ve
r y or, sabrn cuando un enemigo est cerca y sabr cundo atacar.
Captulo 5, acudiendo, describe una situacin donde muchos objetos viajar juntos com
o un grupo. Nos fijaremos en dos diferentes maneras de implementar el bloqueo, y
cmo puede utilizarse para hacer que los objetos se muevan juntos.
El captulo 6, la ruta siguiente y comportamientos de direccin, mira cmo AI personaj
es pueden seguir una ruta proporcionada para llegar a un destino. A continuacin,
examinamos cmo AI personajes pueden ind un destino sin saber una ruta y, moviendo
hacia una meta, evitando al mismo tiempo.

Captulo 7,* Pathinding, discute un popular algoritmo, el cual es utilizado para i


nd la mejor ruta desde una ubicacin determinada en una ubicacin de destino. Con un
*, podemos explorar el terreno y ind el mejor camino que nos conduce a la meta.
El captulo 8, Navegacin Malla, analiza el uso de la fuerza de la unidad para hacer
pathinding ms fciles de implementar. Mediante la creacin de una malla de navegacin
(esto requiere unidad Pro), podremos representar la escena que nos rodea mejor e
ntonces podramos usar azulejos y el algoritmo A*.
El captulo 9, el comportamiento de los rboles, ampla las mquinas de estado finito en
algo que podemos utilizar incluso para los ms complejos de los juegos. Vamos a u
tilizar el plugin gratuito comportarse para ayudarnos a crear y administrar el c
omportamiento de rboles en la unidad.
Captulo 10, Juntando Todo, toma varios elementos de lo que hemos aprendido a lo l
argo de todo el libro, y juntando un ltimo proyecto. Desde aqu usted ser capaz de a
plicar el resto de elementos de AI aprendimos y crear un vehculo imponente juego
de batalla.
Lo que usted necesita para este libro
el requisito principal de este libro es tener unidad versin 3.5 o superior instal
ado.
El captulo 8, la malla de navegacin habla acerca de la creacin de una malla de nave
gacin, algo que requiere la unidad Pro. En el captulo 9, el comportamiento de los r
boles nos descargar comportarse, un comportamiento libre plugin de rbol, que requ
iere una cuenta con la unidad store. Estos dos requisitos son opcionales debido
a que los activos que vienen con este libro ya tienen la malla de navegacin se co
mportan generada y el plugin.
A quin est destinado este manual
Este manual es para cualquier persona que quiera aprender acerca de la incorpora
cin de la inteligencia artificial en los juegos. Este libro est destinado a usuari
os con experiencia previa en el uso de la unidad. Estaremos de codificacin en C#,
de modo que cierta familiaridad con este lenguaje es esperado.
Convenciones
en este libro, usted ind un nmero de estilos de texto que distinguir entre distin
tos tipos de informacin. Aqu estn algunos ejemplos de estos estilos, y una explicac
in de su significado.
Palabras clave en el texto se muestra como sigue: "La clase AdvanceFSM bsicamente
administra todos los FSMState(s) implementa y mantiene actualizado con las tran
siciones, y el estado actual."
[ 2 ],

un bloque de cdigo se establece como sigue:


Usando UnityEngine; using System.Collections; using System.Collections.Generic;
transicin de enumeracin pblica { None = 0,,, LostPlayer SawPlayer ReachPlayer, NoHe
alth, }
nuevos trminos y palabras importantes se muestran en negrita. Las palabras que ve
en la pantalla, en los mens y cuadros de dilogo, por ejemplo, aparecen en el text
o como ste: "Nuestro objeto del depsito es bsicamente una malla simple con un compo
nente Rigidbody."
Advertencias o notas importantes aparecen en un cuadro como ste.
Consejos y trucos aparecen como este.
Reader Comentarios
Comentarios de nuestros lectores es siempre bienvenida. Hganos saber lo que piens
a acerca de este libro-lo que les gust o pueden tener le disgustaba. Reader feedb
ack es importante para nosotros desarrollar ttulos que usted realmente consigue l
a mayora.
Para enviarnos comentarios generales, simplemente enve un correo electrnico a Feed
back@packtpub.com y mencionar el ttulo del libro a travs del asunto de su mensaje.
Si hay un tema que usted tiene experiencia y ests interesado en escribir o contri
buyendo a un libro, vea nuestra gua del autor sobre www.packtpub.com/authors.
Customer support
ahora que usted es el orgulloso propietario de un libro Packt, tenemos una serie
de cosas para ayudarle a sacar el mximo partido de su compra.
[ 3 ]

Descargar el cdigo de ejemplo


puede descargar el cdigo de ejemplo iles Packt para todos los libros que has comp
rado a tu cuenta en http://www.packtpub.com. Si usted compr este libro en otro lu
gar, puede visitar Http://www.packtpub.com/support y registrarse para tener la i
les e-mail directamente a usted.
Descarga de imgenes en color de este libro
tambin le proporcionamos un PDF ile que tiene imgenes en color de los screenshots/
diagramas usados en este libro. Las imgenes en color le ayudarn a entender mejor l
os cambios en la salida.Puedes descargar este ile desde: Http://www.packtpub.com
/sites/ default/files/downloads/3400OT_ColoredImages.pdf
Erratas
Aunque hemos tomado todas las precauciones para garantizar la precisin de nuestro
s contenidos, los errores ocurren. Si ind un error en uno de nuestros libros qui
zs un error en el texto o el cdigo, le agradeceramos que nos informe. Al hacerlo, u
sted puede salvar a otros lectores de frustracin y nos ayudan a mejorar las versi
ones subsiguientes de este libro.
Si ind cualquier errata, por favor reprtelos visitando Http://www.packtpub.com/ e
nviar-erratas, seleccionando el libro, haga clic en el enlace del formulario de
envo de erratas, y entrar en los detalles de su fe de erratas. Una vez que tu las
erratas son veriied, su solicitud ser aceptada y las erratas sern cargados en nue
stro sitio web, o aadido a ninguna lista de erratas existentes, bajo la seccin de
Erratas de ese ttulo. Cualquier errata existente puede visualizarse seleccionando
el ttulo de http://www.packtpub.com/support.
La piratera La
piratera de material protegido por derechos de autor en Internet es un problema c
onstante en todos los medios.
En Packt, tomamos la proteccin de nuestros derechos de autor y licencias muy seri
amente. Si te encuentras con cualquier copias ilegales de nuestras obras, en cua
lquier forma, en Internet, por favor envenos la direccin de ubicacin o nombre del s
itio web inmediatamente para que podamos lograr una solucin.
Pngase en contacto con nosotros en Copyright@packtpub.com con un vnculo a la sospe
cha de material pirateado.
Agradecemos su ayuda en la proteccin de nuestros autores, y nuestra capacidad par
a ofrecerle un contenido valioso.
Preguntas
, puede ponerse en contacto con nosotros en Questions@packtpub.com si tiene algn
problema con algn aspecto del libro, y haremos nuestro mejor esfuerzo para hacer
frente a ella.
[ 4 ]

Introduccin a AI
Este captulo le dar un poco de informacin sobre inteligencia artiicial acadmica trad
icional, dominios y aplicaciones speciic juego. Vamos a aprender cmo la aplicacin
de la inteligencia artificial en los juegos es diferente de otros dominios, y la
importante y requisitos especiales para la inteligencia artificial en los juego
s. Tambin vamos a explorar las tcnicas bsicas de AI que se utiliza en los juegos. E
ste captulo servir como referencia para posteriores captulos, donde podremos aplica
r esas tcnicas de AI en la unidad.
Inteligencia Artiicial (AI) de
organismos vivos como los animales y los seres humanos tienen algn tipo de inteli
gencia que nos ayuda en la toma de una decisin en particular para llevar a cabo a
lgo. Por otro lado, los ordenadores son dispositivos electrnicos que puedan acept
ar los datos, realizar operaciones matemticas y lgicas a altas velocidades, y prod
ucir los resultados. Por lo tanto, Inteligencia Artiicial (AI) es esencialmente
el tema de hacer los ordenadores capaces de pensar y decidir como organismos viv
ientes para realizar operaciones speciic.
Por lo tanto, parece ser que este es un gran tema. Y no hay manera de que este p
equeo libro ser capaz de cubrir todo lo relacionado a la AI. Pero es muy important
e para entender los fundamentos de AI se emplean en diferentes dominios. AI es sl
o un trmino general; sus implementaciones y aplicaciones son diferentes para dife
rentes propsitos, resolver diferentes conjuntos de problemas.

Antes de pasar al juego-speciic tcnicas, echaremos un vistazo a las siguientes rea


s de investigacin en AI:
aplicaciones de visin por computador: es la habilidad para tomar la informacin vis
ual desde fuentes tales como videos y cmaras, y analizarlos para realizar determi
nadas operaciones, tales como el reconocimiento facial, reconocimiento de objeto
s, y el reconocimiento de caracteres pticos.
Procesamiento del Lenguaje Natural (PLN): Es la capacidad que permite a una mquin
a para leer y comprender los idiomas, como solemos hablar y escribir.
El problema es que los lenguajes que utilizamos hoy en da son dificil para mquinas
de entender. Hay muchas maneras de decir la misma cosa, y la misma frase puede
tener diferentes significados segn el contexto. NLP es un paso importante para la
s mquinas, ya que necesitan comprender las lenguas y expresiones que utilizamos,
antes de que pueda procesarlos y responder en consecuencia. Afortunadamente, exi
ste una enorme cantidad de conjuntos de datos disponibles en la Web que pueden a
yudar a los investigadores a hacer un anlisis automtico de un idioma.
el razonamiento de sentido comn: Esta es una tcnica que nuestros cerebros pueden u
tilizar fcilmente para dibujar respuestas incluso desde los dominios no entendemo
s completamente. El sentido comn es un conocimiento comn y habitual manera de trat
ar ciertas cuestiones, ya que nuestros cerebros pueden mezclar y la interaccin en
tre el contexto, conocimientos de fondo y el idioma proiciency.
Pero hacer mquinas para aplicar dichos conocimientos es muy complejo, y sigue sie
ndo un gran desafo para los investigadores.
AI en juegos
juego AI necesita complementar la calidad de un juego. Para eso necesitamos ente
nder la exigencia fundamental de que cada juego debe tener. La respuesta debera s
er fcil. Es el factor de la diversin. Entonces, qu es lo que hace un juego divertido
para jugar? Este es el tema del diseo del juego, y una buena referencia es el ar
te del diseo de juegos por Jesse Schell. Vamos a intentar abordar esta cuestin sin
profundizar en temas de diseo de juegos. Vamos a din que un juego desafiante es
realmente divertido para jugar. Repito: se trata de hacer un juego desafiante. E
sto significa que el juego no debera ser tan difcil que es imposible para el jugad
or a golpear al oponente, o demasiado fcil de ganar. Encontrar el correcto nivel
de desafo es la clave para hacer un juego divertido para jugar.
[ 6 ],

y ah es donde entra en juego la AI. El papel de la IA en juegos es hacerlo divert


ido proporcionando complicados oponentes para competir, e interesantes los perso
najes no jugadores (Pnjs) que se comportan de manera realista dentro del mundo d
el juego. As, el objetivo aqu no es para replicar todo el proceso del pensamiento
del hombre o de los animales, sino hacer que los PNJ parece inteligente al reacc
ionar a las situaciones cambiantes en el mundo del juego en una forma que tenga
sentido para el jugador.
La razn por la que no deseamos hacer el sistema de inteligencia artificial en jue
gos tan caro computacionalmente es que la potencia de procesamiento necesaria pa
ra clculos de AI debe ser compartido entre otras operaciones tales como la repres
entacin grfica y la simulacin de la fsica.
Adems, no olvide que todos ellos estn sucediendo en tiempo real, y tambin es muy im
portante lograr un framerate constante a lo largo del juego. Incluso hubo intent
os de crear procesador dedicado para los clculos (AI AI Buscar Intia del procesad
or).
Con el creciente poder de procesamiento, ahora tenemos ms y ms espacio para clculos
de AI. Sin embargo, al igual que todas las otras disciplinas en el desarrollo d
e juegos, optimizando los clculos de AI sigue siendo un enorme reto para los desa
rrolladores de AI.
Tcnicas de AI
en esta seccin, analizaremos algunos de los AI tcnicas utilizadas en los diferente
s tipos de juegos. Vamos a aprender cmo implementar cada una de estas caracterstic
as en la unidad en los prximos captulos. Ya que este libro no se centra en las tcni
cas de AI en s, sino la aplicacin de esas tcnicas dentro de la unidad, no entraremo
s en demasiados detalles acerca de estas tcnicas aqu. Por lo tanto, vamos a tomar
como un curso intensivo, antes de entrar en la aplicacin. Si desea aprender ms ace
rca de AI para juegos, hay algunas realmente grandes libros, tales como la progr
amacin de juego AI por ejemplo por Mat Buckland y inteligencia Artiicial juegos p
or Ian Millington y John Funge. El juego AI Sabidura Programacin series tambin cont
ienen una gran cantidad de recursos tiles y artculos sobre las ltimas tcnicas de AI.
Las mquinas de estado finito (FSM)
mquinas de estados finitos (FSM) puede ser considerado como uno de los ms sencillo
s AI formulario modelo, y son comnmente utilizados en la mayora de los juegos. Una
mquina de estado consta bsicamente de un inite nmero de Estados que estn conectados
en un grfico, las transiciones entre ellos. Una entidad de juego comienza con un
estado inicial y, a continuacin, mira para los eventos y las reglas que desencad
enar una transicin a otro estado. Una entidad de juego slo puede estar en un estado
exactamente en cualquier momento dado.
[ 7 ]

Por ejemplo, echemos un vistazo a un personaje guardia AI en un tpico juego de di


sparos. Sus miembros podran ser tan simples como el patrullaje, perseguir y dispa
rar.
FSM simple de un carcter protector AI
Existen bsicamente cuatro componentes en un simple FSM:
Miembros: Este componente deines un conjunto de miembros que una entidad de jueg
o o un PNJ puede elegir (patrulla, Chase y disparar)
Las transiciones: Este componente deines relaciones entre diferentes estados Reg
las: Este componente se utiliza para desencadenar una transicin de estado (player
en vista, lo suficientemente cerca para atacar, y perdido/muertos reproductor)
Eventos: Este es el componente que se activar para comprobar las reglas de la gua
rdia (rea visible, la distancia con el jugador, y as sucesivamente)
, de modo que un monstruo en Quake 2 puede tener los siguientes estados: de pie,
caminar, correr, esquivando, atacando, inactiva y bsqueda.
FSMs son ampliamente utilizados en el juego AI especialmente, porque son realmen
te fciles de implementar y ms que suficiente para ambos juegos sencillos y algo co
mplejo.
Usando una simple if/else o switch declaraciones, podemos implementar fcilmente u
na FSM. Puede ser un poco lioso, ya empezamos a tener ms miembros y ms transicione
s. Veremos cmo administrar un simple FSM en el siguiente captulo.
[ 8 ] el

azar y la probabilidad en AI
enemigo Imagine un bot en un juego FPS que siempre puede matar al jugador con un
a escopeta, un oponente en un juego de carreras que siempre elige la mejor ruta,
y adelanta sin colisin con algn obstculo. Ese nivel de inteligencia har el juego ta
n difcil que resulta casi imposible de ganar. Por otra parte, imaginar un AI enem
igo que elige siempre la misma ruta a seguir, o intenta escapar del reproductor.
Entidades controlados por la IA se comporta de la misma manera cada vez que el
jugador se encuentre, hace el juego predecible y fcil de ganar.
Ambas situaciones previas afectan evidentemente a la faceta ldica del juego, y ha
cer que el jugador se sienta como el juego no es difcil ni justa ya suficientes.
Una forma de ix esta especie de perfecto y estpido AI AI es presentar algunos err
ores en su inteligencia. En los juegos, el azar y las probabilidades son aplicad
os en el proceso de toma de decisiones de los clculos de AI. Las siguientes son l
as principales situaciones cuando queremos dejar nuestras entidades AI cambiar a
leatoriamente una decisin:
No intencional: Esta situacin es a veces un juego agent, o quizs un NPC que necesi
te para tomar una decisin al azar, simplemente porque no tiene suficiente informa
cin para tomar una decisin perfecta, y/o realmente no importa qu decisin se hace. Si
mplemente tomar una decisin de forma aleatoria y esperando el mejor resultado es
el camino a seguir en una situacin como esta.
intencional: Esta situacin es perfecto para la AI AI y estpido. Como vimos en los
ejemplos anteriores, tendremos que aadir algunos aleatoriedad intencionadamente,
para hacerlos ms realistas, y tambin para que coincida con el nivel de dificultad
que el jugador se sienta cmodo con l. Tal aleatoriedad y probabilidad podran utiliz
arse para cosas tales como golpear las probabilidades, ms o menos dao aleatorio en
la parte superior de dao base. Con la aleatoriedad y probabilidad podemos aadir u
na sensacin de incertidumbre realista para nuestro juego y hacer nuestro sistema
AI algo impredecible.
Tambin podemos utilizar la probabilidad de deine diferentes clases de personajes
controlados por la IA. Veamos el hroe personajes de defensa de los antiguos (DotA
), que es una accin popular de estrategia en tiempo real (RTS) modo de juego de W
arcraft III. Existen tres categoras de hroes sobre la base de los tres principales
atributos: fuerza, inteligencia y agilidad. La fortaleza es la medida de la fue
rza fsica del hroe, mientras que el intelecto se refiere a qu tan bien el hroe puede
controlar los hechizos y magia. Agilidad deines un hroe tiene la capacidad para
evitar ataques y atacar rpidamente. Un hroe de la resistencia AI categora tendr la p
osibilidad de hacer ms dao durante el combate, mientras que un hroe de inteligencia
tendr ms posibilidades de xito a la puntuacin mayor dao con hechizos y magia. Equili
brando cuidadosamente la aleatoriedad y probabilidad entre diferentes clases y l
os Hroes, hace el juego mucho ms desafiante, y hace un montn de DotA divertido de j
ugar.
[ 9 ]

El sistema de sensores
nuestros caracteres AI necesita saber acerca de sus alrededores, y el mundo estn
interactuando con, a fin de tomar una decisin en particular. Tal informacin podra s
er como sigue:
La posicin del jugador: se utiliza esta informacin para decidir si atacar o chase,
o mantener el patrullaje
edificios y objetos cercanos: Esta informacin se utiliza para ocultar o cubrir la
salud del jugador y su propio estado de salud: Esta informacin restante se utili
za para decidir si retirarse o anticipo
Ubicacin de recursos en el mapa en un juego RTS: Esta informacin se utiliza para o
cupar y reunir los recursos necesarios para la construccin y la produccin de otras
unidades
como puede ver, puede variar mucho dependiendo del tipo de juego que estamos int
entando construir. As que, cmo podemos recoger esa informacin?
Uno de los mtodos de sondeo para recopilar dicha informacin es el sondeo. Podemos
hacerlo if/else o
switch verifica en el mtodo FixedUpdate de nuestro carcter de AI. AI personaje slo
sondea la informacin que ellos estn interesados en el mundo del juego, los controle
s, y acta en consecuencia. Mtodos de sondeo funciona muy bien, si no hay demasiada
s cosas a revisar. Sin embargo, es posible que algunos caracteres no necesita pa
ra sondear el mundo unidos cada fotograma. Caracteres diferentes pueden requerir
diferentes tipos de sondeo. Por lo tanto, generalmente en grandes juegos ms comp
lejos sistemas de AI, necesitamos implementar un mtodo controladas por eventos ut
ilizando un sistema global de mensajera.
El sistema de mensajera
AI no toma decisiones en respuesta a los acontecimientos en el mundo. Los evento
s se comunican entre la entidad AI y el jugador, el mundo, o a las otras entidad
es de AI a travs de un sistema de mensajera. Por ejemplo, cuando el jugador ataca
a un enemigo desde un grupo de la unidad de patrulla de guardias, las otras unid
ades AI necesita saber acerca de este incidente, as que puede empezar a buscar y
atacar al jugador. Si se utiliza el mtodo de sondeo, nuestro AI entidades tendrn q
ue comprobar el estado de todas las dems entidades de AI, con el fin de saber ace
rca de este incidente. Pero con un sistema de mensajera basado en eventos, podemo
s aplicar esto de una manera escalable y ms manejable.
Los personajes controlados por la IA interesados en un determinado evento puede
ser registrado como oyentes, y si eso ocurre, nuestro sistema de mensajera difund
ir a todos los oyentes. La AI entidades entonces puede proceder a tomar las accio
nes apropiadas, o realizar comprobaciones adicionales.
[ 10 ]

El sistema orientado a eventos no necesariamente proporciona ms rpido mecanismo de


sondeo. Pero proporciona un cmodo sistema de control central que percibe el mund
o e informa a los interesados agentes de IA, en lugar de que cada agente individ
ual a tener que comprobar el mismo evento en cada fotograma. En realidad, tanto
la votacin y sistema de mensajera son usados juntos la mayor parte del tiempo. Por
ejemplo, AI puede sondear para obtener informacin ms detallada cuando se recibe u
n evento desde el sistema de mensajera.
Flocado, arrollando, y pastoreo de
muchos seres vivos como los pjaros, ish, insectos y animales terrestres realizar
determinadas operaciones, como mover, caza y forrajeando en grupos. Permanezcan
y cazan en grupos, porque nos hace ms fuerte y segura de los depredadores que per
siguen metas individualmente. Digamos que queremos un grupo de aves, bloqueo pul
ulando alrededor en el cielo; le costar demasiado tiempo y esfuerzo a los animado
res para disear el movimiento y animaciones de cada pjaro. Pero si queremos aplica
r algunas reglas simples para cada pjaro a seguir, podemos conseguir inteligencia
emergente de todo el grupo con el complejo comportamiento global.
Un pionero de este concepto es Craig Reynolds, quien present un algoritmo de bloq
ueo en su papel de SIGGRAPH 1987, manadas, rebaos y escuelas - un modelo de compo
rtamiento distribuidos. Acu el trmino "boid" que suena como "Bird", pero hace refer
encia a un "objeto" de pjaro. Propone tres reglas sencillas que se aplican a cada
unidad, que son como sigue:
Separacin: Esta regla se usa para mantener una distancia mnima con la vecina boido
s para evitar estrellarse contra ellos
Alineacin: Esta regla se usa para alinearse con la direccin media de sus vecinos y
, a continuacin, desplazarse a la misma velocidad con ellos como un bloqueo
Cohesin: Este paso se utiliza para mantener una distancia mnima con el centro de m
asas del grupo
estas tres reglas sencillas son todo lo que necesitamos para aplicar un criterio
realista y un complejo comportamiento de bloqueo para las aves. Tambin se pueden
aplicar a un grupo de comportamientos de cualquier otro tipo de entidad, con po
ca o ninguna modiications. Examinaremos cmo implementar un sistema de bloqueo de
la unidad en el Captulo 5, flocado.
Descarga de imgenes en color de este libro
tambin le proporcionamos un PDF ile que tiene imgenes en color de los screenshots/
diagramas usados en este libro. Las imgenes en color le ayudarn a entender mejor l
os cambios en la salida.Puedes descargar este ile desde: Http://www.packtpub.com
/sites/ default/files/downloads/3400OT_ColoredImages.pdf
[ 11 ]

Ruta Siguiente direccin y,


a veces, queremos que nuestros personajes controlados por la IA para vagar en el
mundo del juego, tras una casi o completamente deined ruta guiada. Por ejemplo,
en un juego de carreras, los adversarios de ia necesidad de navegar en la carre
tera. Y la toma de decisiones algoritmos como nuestro algoritmo boid bloqueo dis
cutido ya, slo puede hacer bien en la toma de decisiones. Pero al final, todo se
reduce a tratar con movimientos reales y comportamientos de direccin. Comportamie
ntos de direccin para caracteres AI han sido en temas de investigacin desde hace u
n par de dcadas. Un papel notable en este ield es la direccin autnoma de los compor
tamientos de los personajes, de nuevo por Craig Reynolds, presentada en 1999 en
la Conferencia de desarrolladores de juegos (GDC). Se clasifican los comportamie
ntos de direccin en las siguientes tres capas:
Jerarqua de comportamientos de movimiento
permtanme citar el ejemplo original de su documento para entender estas tres capa
s:
"Consideremos, por ejemplo, algunos vaqueros tendiendo un rebao de ganado fuera d
e la gama.
Una vaca se aleja de la manada. El trail boss narra un vaquero para capturar los
callejeros. El vaquero dice "sonriente" a su caballo, y lo gua a la vaca, posibl
emente evitando obstculos en el camino. En este ejemplo, el jefe de caminos repre
senta la seleccin de acciones, notando que el estado del mundo ha cambiado (una v
aca dej el rebao), y el establecimiento de un objetivo (recuperar la parsita). El n
ivel directivo est representado por el vaquero que descompone el objetivo en una
serie de objetivos (enfoque simple sub la vaca, evitar los obstculos y recuperar
la vaca). Un sub-objetivo corresponde a un comportamiento de la direccin para el
vaquero y equipo del caballo. Utilizando varias seales de control (comandos de vo
z, espuelas y riendas), el vaquero dirige su caballo hacia el objetivo. En trmino
s generales, estas seales expresar conceptos como ir ms rpido, ir ms lento, gire a l
a derecha, gire a la izquierda, y as sucesivamente.
El caballo implementa la locomocin. Tomando las seales de control del vaquero como
entrada, el caballo se mueve en la direccin indicada. Esta propuesta es el resul
tado de una compleja interaccin de la percepcin visual del caballo, su sentido del
equilibrio, y sus msculos de aplicar los pares de apriete para las articulacione
s de su esqueleto."
[ 12 ]
Luego expuso cmo disear e implementar algunos comportamientos de direccin comn y sen
cillo para cada uno de los personajes controlados por la IA y pares. Tales compo
rtamientos incluyen buscar y lee, perseguir y evadir, errante llegada, superacin
de obstculos, Wall siguiente, y la ruta siguiente. Vamos a aplicar algunos de los
comportamientos en la unidad en el Captulo 6, la ruta siguiente direccin y compor
tamientos.
Una* pathinding
hay muchos juegos que puedes ind monstruos o enemigos que sigue al jugador, o ir
a un punto determinado, evitando obstculos. Por ejemplo, echemos un vistazo a un
tpico juego RTS. Puede seleccionar un grupo de unidades y haga clic en la ubicac
in donde desea que se mueva o haga clic en las unidades enemigas a atacarlos. Tus
unidades necesita ind un camino para llegar a la meta sin chocar con los obstcul
os. Las unidades enemigas tambin deben ser capaces de hacer lo mismo. Los obstculo
s pueden ser diferentes para las distintas unidades. Por ejemplo, una unidad de
la fuerza area podra ser capaz de pasar por encima de una montaa, mientras que el s
uelo o unidades de artillera necesita ind una manera alrededor de ella.
A* (que se pronuncia "estrella") es un algoritmo pathinding ampliamente usado en
juegos, debido a su rendimiento y precisin. Veamos un ejemplo para ver cmo funcio
na.
Supongamos que queremos que nuestra unidad para desplazarse desde un punto A has
ta un punto B, pero hay una pared en el camino, y no puede ir directamente hacia
el objetivo. As, es preciso ind una manera al punto B evitando la pared.
Vista desde arriba de nuestro mapa
[ 13 ]

estamos mirando un simple ejemplo 2D. Pero la misma idea puede aplicarse a entor
nos 3D. A fin de ind la ruta desde un punto A hasta un punto B, necesitamos sabe
r ms sobre el mapa, como la posicin de los obstculos. Por eso podemos dividir todo
nuestro mapa en pequeas baldosas, representando todo el mapa en un formato de cua
drcula, como se muestra en el siguiente grfico:
mapa representado en una cuadrcula 2D
Los azulejos pueden ser tambin de otras formas como hexgonos y tringulos. Pero lo q
ue haremos es utilizar mosaicos cuadrados aqu, ya que es bastante simple y sufici
ente para nuestro escenario. Que representa el mapa entero en una cuadrcula, hace
que el rea de bsqueda ms simpliied, y este es un paso importante en pathinding. Ah
ora podemos hacer referencia nuestro mapa en una pequea matriz 2D.
Nuestro mapa est representado ahora por una cuadrcula de 5 x 5 mosaicos cuadrados
con un total de 25 fichas.
Podemos iniciar la bsqueda de la mejor ruta para llegar a la meta. Cmo lo hacemos?
Calculando el movimiento puntuacin de cada azulejo adyacente a la partida, que es
un mosaico Mosaico en el mapa no ocupado por un obstculo y, a continuacin, elegir
el azulejo con el menor costo.
Hay cuatro posibles baldosas adyacentes al jugador, si no consideramos los movim
ientos en diagonal. Ahora, necesitamos saber dos nmeros para calcular la puntuacin
de movimiento para cada uno de los azulejos. Vamos a llamarlos G y H, donde G e
s el costo del movimiento de arranque actual mosaico Mosaico, y H es el costo pa
ra alcanzar la meta de mosaico mosaico actual.
[ 14 ]

aadiendo G y H, podemos obtener el inal puntuacin de ese mosaico; llammosle F. as qu


e vamos a estar utilizando esta frmula: F = G + H.
vlido baldosas adyacentes
en este ejemplo, utilizaremos un mtodo sencillo llamado Manhattan longitud (tambin
conocida como geometra de taxi), en la que nos acaba de contar el nmero total de
fichas entre el punto de partida y la meta de mosaico Mosaico para saber la dist
ancia entre ellos.
Calcular G
[ 15 ]

El grfico anterior muestra los clculos de G con dos caminos diferentes. Acabamos d
e aadir uno (el cual es el costo para mover un mosaico) para el azulejo anterior
del G puntuacin para obtener la puntuacin actual de G del mosaico actual. Podemos
dar diferentes costos para diferentes azulejos. Por ejemplo, podramos querer dar
un movimiento mayor costo para movimientos en diagonal (si estamos considerando)
, o para baldosas speciic ocupados por, digamos que un estanque o un camino fang
oso. Ahora sabemos cmo obtener G. veamos el clculo de H. El siguiente grfico muestr
a los diferentes valores H de partida diferentes azulejos azulejos al destino. U
sted puede intentar contar las casillas entre ellos para entender cmo podemos obt
ener esos valores.
Calcular H
as, ahora sabemos cmo obtener G y H. volvamos a nuestro ejemplo original de lustra
cin fuera la ruta ms corta desde A a B. nos irst elija el mosaico de arranque y, a
continuacin, determinar la validez de los azulejos adyacentes, como se muestra e
n el siguiente grfico. A continuacin, calculamos el G Y H decenas de cada mosaico,
que se muestra en la esquina inferior izquierda y derecha de las esquinas de la
teja, respectivamente.
Y luego el inal puntuacin F, que es G + H es mostrado en la esquina superior izqu
ierda. Obviamente, el mosaico a la derecha inmediata del mosaico de inicio tiene
el menor F puntuacin.
[ 16 ]

Por lo tanto, elegimos este mosaico como nuestro prximo movimiento y almacenar el
azulejo anterior como su padre.
Este padre stuff ser til ms adelante, cuando trazamos nuestro camino inal.
La posicin inicial
del actual mosaico, hacemos el proceso similar de nuevo, determinar la validez b
aldosas adyacentes. Esta vez slo hay dos vlidas baldosas adyacentes en la parte su
perior e inferior. El azulejo izquierdo es un mosaico de arranque, que ya hemos
examinado, y el obstculo ocupa el azulejo derecho. Calculamos el G, H, y luego la
puntuacin F de esas nuevas baldosas adyacentes. Esta vez tenemos cuatro fichas e
n nuestro mapa con todos los que tengan la misma puntuacin, seis.
Por lo tanto, que no podemos elegir? Podemos elegir cualquiera de ellos. No impo
rta en este ejemplo, porque vamos a eventualmente ind la ruta ms corta de mosaico
con cualquiera que elija, si tienen la misma puntuacin. Normalmente, acabamos de
elegir el azulejo aadidas ms recientemente a nuestra lista contigua. Esto es porq
ue ms adelante vamos a usar algn tipo de estructura de datos, tales como una lista
para almacenar las fichas que estn siendo considerados para el siguiente movimie
nto. Por lo tanto, acceder a las baldosas ms recientemente aadidos a esa lista pod
ra ser ms rpida que la bsqueda a travs de la lista hasta llegar a un determinado mosa
ico que fue agregado anteriormente.
[ 17 ]
En esta demostracin, lo que haremos es elegir aleatoriamente el mosaico para nues
tra prxima prueba, slo para demostrar que realmente puede ind la ruta ms corta.
Segundo paso
por lo tanto, elegimos este mosaico, que est resaltada con un borde rojo. Volvemo
s a examinar las baldosas adyacentes. En este paso, slo hay una nueva ficha adyac
ente con una puntuacin de 8 F calculado. As, la puntuacin ms baja ahora todava es 6.
Podemos elegir el mosaico con la puntuacin 6.
Tercer paso
[ 18 ]

Por lo tanto, elegimos un mosaico aleatoriamente entre todos los azulejos con la
puntuacin 6. Si repetimos este proceso hasta que alcancemos nuestra meta de mosa
ico, terminaremos con un tablero completo con todas las puntuaciones de cada mos
aico vlidos.
Alcanzar
ahora todo lo que tenemos que hacer es rastrear a partir del mosaico de destino
utilizando su padre mosaico. Esto dar una ruta parecida en el siguiente grfico:
ruta remonta
[ 19 ]

Por lo que este es el concepto de una* pathinding en una cscara de nuez, sin most
rar ningn cdigo.
A* es un concepto importante en el rea pathinding AI, pero desde la unidad 3.5, h
ay un par de nuevas caractersticas como la navegacin automtica la generacin de malla
y la malla Nav Agent, que veremos aproximadamente en la siguiente seccin y luego
en ms detalle en el Captulo 8, la malla de navegacin . Estas caractersticas hacen d
e la aplicacin pathinding en tus juegos mucho ms fcil. De hecho, puede que ni siqui
era necesita saber acerca de un* para aplicar pathinding para tus personajes con
trolados por la IA. No obstante, saber cmo funciona realmente el sistema detrs de
las escenas le ayudar a convertirse en un slido AI programador. Lamentablemente, e
sas funciones de navegacin avanzadas en la unidad slo estn disponibles en la versin
Pro en este momento.
Una malla de navegacin
ahora tenemos alguna idea de A* pathinding tcnicas. Una cosa que puede observar e
s que el uso de una simple rejilla en un* requiere un buen nmero de clculos para o
btener una ruta que es la ms corta hasta el destino y, al mismo tiempo, evita los
obstculos. As, para hacer que sea ms barato y ms fcil para caracteres AI para ind un
a ruta, la gente vino con la idea de utilizar puntos de referencia como gua para
mover caracteres AI desde el punto inicial hasta el punto de destino. Supongamos
que queremos mover nuestro personaje AI desde un punto A hasta un punto B, y he
mos establecido tres puntos de referencia como se muestra en el siguiente grfico:
Waypoints
[ 20 ]

Todo lo que tenemos que hacer ahora es coger el punto de referencia ms cercano y,
a continuacin, siga su nodo conectado al destino principal punto de referencia.
La mayora de los juegos usan puntos de referencia para los pathinding, porque son
simples y muy eficaces en el uso de menos recursos de computacin. Sin embargo, t
ienen algunos problemas. Qu ocurre si queremos actualizar los obstculos en nuestro
mapa? Tambin tendremos que colocar waypoints para el mapa actualizado de nuevo, c
omo se muestra en el siguiente grfico:
nuevos puntos de referencia
despus de cada nodo a la meta puede significar la AI personaje se mueve en zigzag
direcciones. Mirar las figuras anteriores; es muy probable que la AI carcter cho
car con la pared donde la ruta est cerca de la pared. Si eso ocurre, nuestro AI se
guir intentando atravesar la pared para llegar al siguiente destino, pero no podr
y se atascan. Aunque podemos allanar el camino en zigzag al transformarla en una
ranura y hacer algunos ajustes para evitar tales obstculos, el problema es el wa
ypoints no dan ninguna informacin sobre el medio ambiente, otros de la spline con
ectadas entre dos nodos. Qu ocurre si nuestra ruta ajustada suavizada y pasa al bo
rde de un acantilado o un puente? La nueva ruta podra no ser una ruta segura ya.
Por lo tanto, para nuestras entidades AI para ser capaz de atravesar todo el niv
el, vamos a necesitar un enorme nmero de waypoints, que ser muy difcil de implement
ar y administrar.
[ 21 ]

veamos una solucin mejor, malla de navegacin. Una malla de navegacin es otra estruc
tura de grafo que se puede utilizar para representar nuestro mundo, similar a la
manera en que lo hicimos con nuestros azulejos cuadrados cuadrcula basada en pun
tos de referencia o grfico.
Malla de navegacin
navegacin utiliza una malla de polgonos convexos para representar las reas del mapa
que una entidad AI puede viajar. El ms importante de beneit utilizando una malla
de navegacin es que da mucha ms informacin sobre el entorno de un sistema de punto
de referencia.
Ahora podemos ajustar nuestro camino de manera segura, porque sabemos que la seg
uridad de la regin en la que nuestras entidades AI puede viajar. Otra ventaja de
utilizar una malla de navegacin es que podemos utilizar la misma malla para difer
entes tipos de entidades de AI. AI diferentes entidades pueden tener diferentes
propiedades como el tamao, la velocidad y la capacidad de movimiento. Un conjunto
de waypoints est adaptada para los derechos humanos, AI puede no funcionar bien
para mentir o criaturas vehculos controlados por la IA. Estos podran necesitar dif
erentes conjuntos de waypoints. Utilizando una malla de navegacin puede ahorrar u
n montn de tiempo en tales casos.
Pero generar una malla de navegacin mediante programacin basada en una escena, es
un proceso algo complicado. Afortunadamente, la unidad 3.5 introdujo una explora
cin integrada generador de malla (Slo Pro). Dado que este no es un libro sobre cor
e AI tcnicas, no entraremos en demasiados realmente cmo generar y utilizar dicha n
avegacin mallas. En su lugar, vamos a aprender cmo utilizar la unidad de navegacin
de malla para la generacin de funciones para implementar fcilmente nuestro pathind
ing AI.
[ 22 ]

El comportamiento el
comportamiento de los rboles Los rboles son las otras tcnicas que se utilizan para
representar y controlar la lgica detrs de personajes controlados por la IA. Ellos
se han convertido en muy popular para las aplicaciones en AAA juegos como Halo y
espora. Previamente, hemos cubierto briely FSM. FSMs proporcionan una forma muy
sencilla de deine la lgica de un personaje de AI, basada en los diferentes estad
os y transiciones entre ellos. Sin embargo, el FSM se consideran difcil de escala
r y re-usar lgica existente. Necesitamos agregar muchos estados y cablear muchas
transiciones, con el fin de apoyar a todos los escenarios, en los que queremos q
ue nuestro personaje AI a considerar. Por lo tanto, necesitamos un enfoque ms esc
alable al tratar con grandes problemas. El comportamiento de los rboles son la me
jor manera de implementar IA personajes que podran ser ms y ms compleja.
Los elementos bsicos del comportamiento de los rboles son tareas, donde los estado
s son los principales elementos de FSMs. Hay varias tareas como la secuencia, Se
lector, paralelo y decorador. Esto es bastante confuso. La mejor manera de compr
ender esto es un vistazo a un ejemplo. Vamos a tratar de traducir nuestro ejempl
o del FSM seccin mediante un comportamiento de rbol. Podemos romper todas las tran
siciones y estados en las tareas.
Tareas
[ 23 ]

veamos un selector tarea para este comportamiento de rbol. Tareas de seleccin estn
representados con un crculo y un signo de interrogacin en su interior. En primer l
ugar, escogeremos a atacar al jugador. Si el ataque tarea devuelve SUCCESS, el S
elector de tareas y volver al nodo primario, si hay uno. Si la tarea de ataque fa
lla, probar el Chase tarea. Si el Chase tarea falla, probar las tareas de patrulla
.
Qu tarea Selector acerca de las pruebas? Son tambin una de las tareas en el comport
amiento de los rboles. El siguiente diagrama muestra el uso de la secuencia de ta
reas, indicada por un rectngulo con una flecha en su interior. El selector de raz
pueden elegir el irst accin de la secuencia. Esta secuencia de accin irst tarea es
verificar si el jugador est lo suficientemente cerca como para atacar.
Si esta tarea se realiza correctamente, se podr continuar con la siguiente tarea,
que es atacar al jugador. Si la tarea de ataque tambin devuelve el xito, toda la
secuencia devolver el xito y el selector est hecho con este comportamiento, y no co
ntinuar con otras tareas de secuencia.
Si el lo suficientemente cerca como para atacar? Tarea falla, entonces la accin d
e la secuencia no se proceder a la tarea de ataque, y devolver un estado fallido a
l selector principal tarea. A continuacin, el selector se elige la tarea siguient
e en la secuencia, perdidos o muertos reproductor?.
Secuenciar las tareas
[ 24 ]

Los otros dos componentes comunes son paralelas y decorador. Una tarea paralela
ejecutar todas sus tareas secundarias al mismo tiempo, mientras que el selector y
la secuencia de tareas slo ejecuten sus tareas secundarias uno por uno. Decorado
r es otro tipo de tarea que tiene un solo hijo. Puede cambiar el comportamiento
de su propio hijo, que incluye tareas si desea ejecutar la tarea de su hijo o no
, cuntas veces se debe ejecutar, y as sucesivamente.
Estudiaremos cmo implementar un sistema de rbol de comportamiento bsicos en la unid
ad en el Captulo 9, el comportamiento de los rboles. Hay un complemento gratuito p
ara la unidad denominada comportarse en la unidad tienda de activos.
Se comportan es un til, libre editor GUI para configurar el comportamiento de rbol
es de personajes controlados por la IA, y lo estudiaremos con ms detalle ms adelan
te.
La locomocin de
los animales (incluidos los humanos) tienen un muy complejo sistema musculoesque
ltico (aparato locomotor) que les da la capacidad de moverse alrededor del cuerpo
usando los sistemas muscular y esqueltico. Sabemos dnde poner nuestros pasos al s
ubir una escalera, escaleras, o en terrenos irregulares, y sabemos cmo equilibrar
nuestro cuerpo para estabilizar todos los elegantes plantea que queremos hacer.
Podemos hacer todo esto con nuestros huesos, msculos, articulaciones y otros tej
idos, descritas colectivamente como nuestro aparato locomotor.
Ahora poner esto en nuestro juego perspectiva de desarrollo. Imaginemos que tene
mos un carcter humano que necesita para caminar en ambos incluso y superficies ir
regulares o en laderas, y nosotros slo tenemos una animacin para una "caminata" ci
clo. Con la falta de un aparato locomotor en nuestro personaje virtual, esto es
como se vera:
subir escaleras sin locomocin
[ 25 ]

primero nos toca el pie de animacin y avanzar el jugador avance. Ahora que conoce
el personaje es penetrar en la superficie. As, el sistema de deteccin de colision
es se tire al personaje hacia arriba por encima de la superficie para evitar est
a penetracin. Esto es cmo se suelen configurar el movimiento sobre una superficie
irregular. Aunque no da un aspecto realista, que hace el trabajo y es barata de
implementar.
Echemos un vistazo a cmo podemos realmente caminar hasta las escaleras. Ponemos n
uestro paso irmly en la escalera, y el uso de esta fuerza nos tire hacia arriba
el resto de nuestro cuerpo para el siguiente paso. As es cmo lo hacemos en la vida
real con nuestro avanzado sistema locomotor. Sin embargo, no es tan fcil de apli
car este nivel de realismo en los juegos. Necesitaremos un montn de animaciones p
ara diferentes escenarios, que incluyen subir escaleras, caminar/correr escalera
s arriba, y as sucesivamente. As, slo los grandes estudios, con un montn de animador
es podran sacar de esto en el pasado, hasta que nos topamos con un sistema automa
tizado.
Con un sistema de locomocin
Afortunadamente, Unity 3D tiene una extensin que puede hacer justamente eso, que
es un sistema de locomocin.
[ 26 ] La

Unidad de extensin del sistema de locomocin


este sistema puede mezclar automticamente nuestro animado paseo/ciclos de ejecucin
y ajustar los movimientos de los huesos de las piernas para garantizar que el p
aso correctamente los pies en el suelo. Tambin puede ajustar las animaciones orig
inales realizados para una velocidad y direccin speciic sobre cualquier superfici
e, medidas arbitrarias y pendientes. Veremos cmo usar este sistema de locomocin pa
ra aplicar el movimiento realista a nuestros personajes controlados por la IA en
un captulo posterior.
[ 27 ] El

algoritmo de Dijkstra
el algoritmo de Dijkstra, nombrado despus de que el profesor Edsger Dijkstra, qui
en ide el algoritmo, es uno de los ms famosos algoritmos para encontrar las rutas
ms cortas en una grfica con borde no negativo, los costos de la ruta. El algoritmo
fue diseado originalmente para resolver el problema de la ruta ms corta en el con
texto de la teora de grficos matemticos. Y es diseado para ind todas las rutas ms cor
tas desde un nodo de inicio a todos los otros nodos en el grfico. Dado que la may
ora de los juegos necesitan slo la ruta ms corta entre un punto inicial y un punto
de destino, todas las dems rutas generadas o encontrados por este algoritmo no so
n muy tiles. Podemos detener el algoritmo, una vez nos ind la ruta ms corta desde
un nico punto de partida hasta un punto de destino. Pero an as intentar ind todas la
s rutas ms cortas desde todos los puntos que ha visitado. As, este algoritmo no es
eficient suficiente para ser utilizados en la mayora de los juegos. Y no vamos a
estar haciendo una unidad de demostracin del algoritmo de Dijkstra en este libro
.
Sin embargo, el algoritmo de Dijkstra es un algoritmo importante para los juegos
que requieren AI estratgica que necesita tanta informacin como sea posible sobre
el mapa para tomar decisiones tcticas. Tiene muchas otras aplicaciones que no sea
n juegos, tales como encontrar la ruta ms corta en los protocolos de enrutamiento
de red.
Resumen
juego AI AI y acadmicas tienen objetivos diferentes. AI investigaciones acadmicas
para tratar de resolver los problemas del mundo real, y demostrar una teora sin m
ucho recursos limitados. Juego AI se centra en la creacin de NPCs dentro de los l
imitados recursos que parece ser inteligente para el jugador. El objetivo de la
inteligencia artificial en los juegos es proporcionar un difcil adversario que ha
ce que el juego sea ms divertido para jugar. Tambin hemos aprendido briely acerca
de las diferentes tcnicas de AI, que son ampliamente utilizados en juegos tales c
omo mquinas de estado inite (FSMs), azar y probabilidad, el sensor y el sistema d
e entrada, bloqueo y comportamientos de grupo, ruta de acceso y la direccin sigui
ente comportamientos, AI dentificacin ruta de navegacin, generacin de la malla, y e
l comportamiento de los rboles. Veremos cmo aplicar estas tcnicas dentro de la unid
ad de motor en los siguientes captulos.
[ 28 ]

Las mquinas de estado finito


en este captulo, vamos a aprender a usar el FSM en Unity3D juego, usando una senc
illa mecnica de juego depsito de ejemplo que viene con este libro. Vamos a analiza
r el cdigo y los componentes de este proyecto.
En nuestro juego, el jugador ser capaz de controlar un tanque. Los tanques enemig
os se mueve en la escena con referencia a cuatro puntos. Una vez que el jugador
entra en el depsito de su rango visible, comenzarn a perseguir a nosotros; y una v
ez que estn lo suficientemente cerca como para atacar, empezarn a disparar a nuest
ro jugador tanque. Este simple es suficiente? Implementaremos FSMs para controla
r la IA de nuestro tanque enemigo. Primero vamos a utilizar el interruptor simpl
e declaraciones a aplicar nuestro tanque AI unidos y, a continuacin, utilizaremos
un marco de Micronesia, que se basa en y adaptado de la FSM C# framework, y se
puede encontrar en el siguiente vnculo:
http://wiki.unity3d.com/index.php?title=Finite_State_Machine

el depsito del jugador


ahora, antes de escribir el guin de nuestro depsito de jugador, echemos un vistazo
a cmo podemos configurar el juego PlayerTank objeto. Nuestro tanque es bsicamente
un objeto de malla con un simple componente Rigidbody, y una caja de Hadrones c
omponente. El depsito no es objeto de una nica malla, pero dos mallas, depsito y to
rreta. Hacemos un nio de la torreta del tanque. Esto es para permitir la rotacin i
ndependiente de la torreta objeto mediante el movimiento del ratn. Y, al mismo ti
empo, puesto que es el nio del objeto del depsito, te seguir donde el cuerpo del de
psito va tan bien. A continuacin, cree un objeto de juego vaca para ser nuestro Spa
wnPoint transformacin. Se utilizar como referencia el punto de posicin, cuando se d
ispara una bala. Tambin tenemos que asignar la etiqueta de jugador a nuestro obje
to del depsito. As es cmo nuestro tanque entidad est configurado. Ahora echemos un v
istazo a la clase del controlador.
Entidad de depsito de
la clase PlayerTankController
esta clase ser el principal medio por el cual el jugador controlar el depsito objet
o con ella. Vamos a utilizar el W, A, S y D claves para mover y dirigir el tanqu
e y el botn izquierdo del ratn para apuntar y disparar la torreta objeto.
[ 30 ] La

unidad slo sabe cmo trabajar con el teclado QWERTY estndar. Para aquellos de nosotr
os que usar un teclado diferente, todo lo que tenemos que hacer es fingir que es
tamos utilizando un teclado QWERTY, y entonces todo funcionar el INE.
Este libro tambin asumir la utilizacin de un teclado QWERTY, as como el uso de un ra
tn de dos botones, con el botn izquierdo del ratn para establecer el botn primario d
el mouse.
Inicializacin de
las propiedades de nuestra clase TankController son como sigue. Establecimos nue
stra primera puesta en funcin y las funciones de actualizacin.
El cdigo en el PlayerTankController.cs ile es como sigue:
Usando UnityEngine; using System.Collections;
public class PlayerTankController : MonoBehavior { public GameObject bala; priva
dos de la torreta de transformacin; transformar bulletSpawnPoint privado; privado
s de flotacin, targetSpeed curSpeed, rotSpeed; flotacin privado turretRotSpeed = 1
0.0f; flotacin privado maxForwardSpeed = 300.0f; privados de flotacin -300.0maxBac
kwardSpeed = f;
//tasa de disparo de bala protegida = 0.5f shootRate Flotacin Flotacin; proteccin;
elapsedTime
void Start() {
// Depsito Settings rotSpeed = 150.0f;
//Obtener la torreta de la torreta del tanque = gameObject.transform.GetChild(0)
.transform; bulletSpawnPoint =.GetChild torreta(0).transform; }
[ 31 ]

void Update() { UpdateWeapon(); UpdateControl(); }


El irst nio objeto de nuestro depsito es la entidad objeto de la torreta y el irst
secundario del
objeto es la torreta bulletSpawnPoint. La funcin arranque inds estos objetos y, a
continuacin, les asigna a sus respectivas variables. Asignaremos nuestra variabl
e de bala despus de crear nuestro objeto de vieta. Tambin hemos incluido la funcin d
e actualizacin, que pide nuestra UpdateWeapon UpdateControl y funciones, que se c
rear en breve.
Vieta de disparo
cuando el jugador hace clic en el botn izquierdo del ratn, comprobamos si el total
de tiempo transcurrido desde la ltima ire ire ha superado la tasa de la arma. Si
es as, entonces se crea un nuevo objeto en la vieta SpawnPoint la posicin variable
. De esta manera, podemos evitar disparar continuamente sin ningn lmite.
void UpdateWeapon() { if (Input.GetMouseButtonDown(0)) { elapsedTime Tiempo +=.d
eltaTime; si >= shootRate (elapsedTime) { //restablecer el tiempo = 0.0f elap
sedTime; //Crear instancias de la bala instanciar(Vieta bulletSpawnPoint.posicin,
bulletSpawnPoint.rotacin); } } }
controlando el tanque
al jugador girar la torreta objeto utilizando el ratn. As, esta parte es un poco c
omplicada. Nuestra Cmara se mira hacia abajo a los battleield. Desde que usaremos
ray casting para determinar la direccin de giro, basado en el objeto en el battl
eield mousePosition.
void UpdateControl() { //apuntando con el ratn //Crear un plano que intersecta la
transformacin
[ 32 ]

//posicin con arriba de lo normal.


Avin playerPlane = nuevo avin(vector3.up, transform.posicin + nuevo Vector3(0, 0, 0
);
// generar un rayo desde la posicin del cursor Ray RayCast = Cmara.main.ScreenPoin
tToRay(Input.mousePosition);
//determinar el punto en el que el cursor se cruza con ray //el avin.
float HitDist = 0;
// Si el rayo es paralelo al plano, Raycast //devolver false.
Si (playerPlane.Raycast(RayCast, HitDist)) { //Obtener el punto a lo largo del r
ayo que golpea el //distancia calculada.
Vector3.GetPoint RayCast RayHitPoint =(HitDist);
Quaternion targetRotation = Quaternion.LookRotation(RayHitPoint - transform.posi
cin);
.transform.la rotacin de la torreta = Quaternion.Slerp(.transform.la rotacin de la
Torreta, targetRotation, tiempo.deltaTime * turretRotSpeed); }
Raycast para apuntar con el ratn
[ 33 ]

As es cmo funciona:
1. Configurar un plano que intersecta con el jugador el depsito con una trayector
ia normal.
2. Disparar un rayo desde el espacio de la pantalla con la posicin del ratn (en el
diagrama anterior, se supone que estamos mirando hacia el depsito).
3. Encontrar el punto donde el rayo intercepta el plano.
4. Por ltimo, ind la rotacin desde la posicin actual hasta que el punto de intersec
cin.
A continuacin, se comprueba si la tecla presionada, entradas y, a continuacin, mov
er o girar el depsito correspondiente.
Si (Input.GetKey(KeyCode.W)) { targetSpeed = maxForwardSpeed; } else if (Input.G
etKey(KeyCode.S) { targetSpeed = maxBackwardSpeed; } else { targetSpeed = 0; }
Si (Input.GetKey(KeyCode.a)) { transform.Rotate(0, -rotSpeed * Tiempo.deltaTime,
0.0F); } else if (Input.GetKey(KeyCode.D)) { transform.Rotate(0, *.deltaTime ro
tSpeed Tiempo, 0.0F); }
//determinar velocidad actual curSpeed = Mathf.Lerp(curSpeed, targetSpeed, 7.0f
* Tiempo.deltaTime);
transform.translate(vector3.forward * Tiempo.deltaTime * curSpeed); } }
[ 34 ]
La bala
siguiente nuestra clase Bullet prefab est configurado con dos planos ortogonales
using laser-como materiales, y partculas/aditivo en el sombreado ield.
Bullet prefab
el cdigo en la vieta.cs ile es como sigue:
Usando UnityEngine; using System.Collections;
public class Bullet : MonoBehavior { //efecto de explosin explosin GameObject pblic
a;
flotacin pblica velocidad = 600.0f; flotacin pblica LifeTime = 3.0f; public int daos
= 50;
[ 35 ]

Start() { void Destroy(gameObject, LifeTime); }


void Update() { transform.posicin += transform.adelante * Velocidad * Tiempo.delt
aTime; }
void OnCollisionEnter(Colisin colisin) { ContactPoint contacto = colisin.contactos[
0]; instanciar(explosin.El punto de contacto, Quaternion.identidad); destruir(gam
eObject); } }
tenemos tres propiedades, dao, velocidad y duracin de nuestra bala, de modo que el
proyectil ser destruido automticamente despus de su vida.
Puede ver la explosin de la bala de la propiedad est vinculada a la ParticleExplos
ion prefabricados, que no vamos a discutir en detalle. Hay un lugar prefabricado
denominado ParticleEffects ParticleExplosion bajo la carpeta. Acabamos de gota
que prefab en este ield. Este efecto de partculas se reproduce cuando el proyecti
l es golpeado con algo como se describe en el mtodo OnCollisionEnter. Este Partic
leExplosion prefab utiliza un script llamado AutoDestruct para destruir el objet
o explosin automticamente despus de un cierto perodo de tiempo.
Descargar el cdigo de ejemplo
puede descargar el cdigo de ejemplo iles Packt para todos los libros que has comp
rado a tu cuenta en http://www.packtpub.com. Si usted compr este libro en otro lu
gar, puede visitar: http://www.
Packtpub.com/support y registrarse para tener la iles e-mail directamente a uste
d.
[ 36 ]

establecer puntos de referencia


siguiente, ponemos cuatro objetos del juego de cubos en lugares al azar, como pu
ntos de referencia dentro de nuestra escena, y asignarles nombre WandarPoints.
WanderPoints
aqu es lo que nuestro objeto WanderPoint tendr el aspecto siguiente:.
Propiedades WanderPoint
[ 37 ]

Una cosa a la nota aqu es la necesidad de etiquetar estos puntos con una etiqueta
denominada WandarPoint.
Estaremos haciendo referencia a esta etiqueta, cuando tratamos de ind los waypoi
nts desde nuestro tanque AI.
Como se puede ver en sus propiedades, un punto de referencia aqu es slo un juego d
e cubo con la malla del objeto checkbox Renderer desactivado, y el cuadro de Had
rones objeto eliminado. Incluso podemos usar un objeto juegos vaca, ya que todos
necesitamos de un punto de referencia es su posicin y la transformacin de datos. P
ero estamos usando el cubo objetos aqu, de modo que podemos visualizar los puntos
de referencia si queremos.
El resumen
siguiente clase EFM, implementaremos una clase abstracta que deines genrica los mt
odos que nuestro tanque enemigo AI Clase tiene que implementar.
El cdigo de los EFM.cs ile es como sigue:
Usando UnityEngine; using System.Collections;
public class FSM : MonoBehavior { //Player transformar transformar playerTransfo
rm protegidas;
//prximo destino posicin del tanque NPC protegido destPos Vector3;
//Lista de puntos para patrullar protegido pointList GameObject[];
//tasa de disparo de bala protegida shootRate Flotacin Flotacin; protegidos elapse
dTime;
//Depsito pblico torreta torreta transformacin { GET; set; } bulletSpawnPoint trans
formacin pblica { GET; set; }
virtual protegido void Initialize() { } void FSMUpdate virtual protegido() { } v
oid FSMFixedUpdate virtual protegido() { }
// Usar este para inicializacin void Inicio () {
[ 38 ]

Initialize(); }
// se llama a Update una vez por fotograma vaco actualizacin () { FSMUpdate(); }
void FixedUpdate() { FSMFixedUpdate(); } }
todo lo que Los tanques enemigos necesita saber es la posicin del jugador del deps
ito, su prximo punto de destino, y la lista de waypoints para elegir, mientras es
tn patrullando.
Una vez que el jugador depsito est en rango, van a girar la torreta de su objeto y
, a continuacin, comienza a disparar desde el punto de despliegue de bala en su t
asa de IRE.
Las clases heredadas tambin deben implementar los tres mtodos: Initialize,
y FSMFixedUpdate FSMUpdate. Entonces, esta es la clase abstracta, que nuestro ta
nque AI pondr en prctica.
El tanque enemigo AI
Ahora veamos el cdigo real para nuestros tanques de AI. Vamos a llamar a nuestra
clase SimpleFSM, que hereda de la clase abstracta de Micronesia.
El cdigo en el SimpleFSM.cs ile es como sigue:
Usando UnityEngine; using System.Collections;
public class SimpleFSM : FSM {
public enum FSMState { None, patrulla, Chase, Ataque, muertos, }
[ 39 ]

//Estado actual que el CNP est alcanzando FSMState curState pblica;


//velocidad del tanque de flotacin privado curSpeed; //tanque de flotacin privado
curRotSpeed Velocidad de rotacin;
//Bullet Bullet GameObject pblica;
//si el NPC es destruida o no privados bool bDead int privado; salud;
aqu, estamos declarando a algunas variables. Nuestro tanque AI tendr cuatro estado
s diferentes:
PATRULLA, Chase, Ataque y muertos. Bsicamente, estaremos implementando el FSM que
fue descrito como un ejemplo en el Captulo 1, Introduccin a la AI.
Tanque enemigo AI's FSM
en nuestro mtodo Initialize, establecimos nuestra AI tank propiedades con valores
predeterminados.
Entonces almacenamos las posiciones de los puntos de referencia en nuestra varia
ble local. Conseguimos los waypoints desde nuestra escena utilizando el mtodo Fin
dGameObjectsWithTag, intentando ind los objetos con la etiqueta WandarPoint.
//inicializar la mquina de estado finito para el NPC protegido depsito anular void
inicializar () { curState = FSMState.patrulla; curSpeed = 150.0f; curRotSpeed =
2.0f; [ 40 ]

bDead = false; = 0.0f elapsedTime; shootRate = 3.0f; salud = 100;


//Obtener la lista de puntos.FindGameObjectsWithTag GameObject pointList =("Wand
arPoint");
//Set Destination point primera FindNextPoint ALEATORIO();
//Obtener el objetivo enemigo(Jugador) GameObject GameObject.FindGameObjectWithT
ag objPlayer =("Player"); = objPlayer playerTransform.transform;
if (!playerTransform) print("Jugador no existe.. Por favor, aada una "+ "con etiq
ueta denominada "Player"); //Obtener la torreta de la torreta del tanque = gameO
bject.transform.GetChild(0).transform; bulletSpawnPoint =.GetChild torreta(0).tr
ansform; }
Nuestro mtodo Update que se llama cada fotograma tiene el siguiente aspecto:
//Actualizar cada fotograma protegidos void override FSMUpdate() { interruptor (
curState) { caso FSMState.Patrol: UpdatePatrolState(); break; caso FSMState.Chas
e: UpdateChaseState(); break; caso FSMState.Ataque: UpdateAttackState(); break;
caso FSMState.Dead: UpdateDeadState(); break; }
//Actualizar la hora elapsedTime Tiempo +=.deltaTime;
//Ir a estado muerto no es izquierda si la salud (salud <= 0) = FSMState curS
tate.muertos; }
comprobamos el estado actual y, a continuacin, llame al mtodo estatal apropiado. U
na vez que el
objeto de salud es cero o menos de cero, establecemos el depsito al estado muerto
.
[ 41 ]

El estado de patrulla
mientras nuestro depsito est en la patrulla estatal, debemos comprobar si se ha al
canzado el punto de destino. Si lo ha hecho, le ind el prximo punto de destino a
seguir. El
mtodo FindNextPoint bsicamente elige el siguiente punto de destino aleatorio entre
los waypoints deined. Si todava est en el camino hacia el punto de destino actual
, podr comprobar la distancia con el depsito del jugador. Si el jugador del tanque
est en rango (que es de 300 aqu) y, a continuacin, cambiar a la persecucin estatal.
El resto del cdigo simplemente gira el depsito y se mueve hacia adelante.
protected void UpdatePatrolState() { //buscar otro punto de patrulla aleatoria s
i el actual //punto se alcanza si (Vector3.Distancia(transform.posicin, destPos)
<= 100,0 F) { print("lleg al punto de destino\n" + "calcular el siguiente punt
o");
FindNextPoint(); }
//controlar la distancia con el jugador depsito //cuando la distancia est cerca, l
a transicin al estado chase else if (Vector3.Distancia(transform.posicin, playerTr
ansform.position) <= 300.0f) { print("Cambiar a posicin Chase"); curState = FS
MState.Chase; }
//Girar al punto de destino Quaternion targetRotation = Quaternion.LookRotation(
destPos - transform.posicin);
transform.rotacin = Quaternion.Slerp(transform.rotacin, targetRotation, tiempo.del
taTime * curRotSpeed);
//Avanzar transform.translate(vector3.forward * Tiempo.deltaTime * curSpeed); }
protected void FindNextPoint() {
[ 42 ]

print("localizacin prxima point"); int rndIndex = Random.Range(0, pointList.Length


); float rndRadius = 10.0f; Vector3 RndPosition = Vector3.cero; destPos =[rndInd
ex pointList].transform.posicin + rndPosition;
//Rango de comprobacin para decidir el punto aleatorio //como la misma como antes
si (IsInCurrentRange(destPos) { rndPosition = new Vector3(Random.Range(-rndRadi
us, rndRadius), 0.0F, Random.Range(-rndRadius, rndRadius); destPos =[rndIndex po
intList].transform.posicin + rndPosition; } } protegido bool IsInCurrentRange(vec
tor3 pos) { float xPos = Mathf.abs(pos.x - transform.position.x); float zPos = M
athf.abs(pos.z - transform.position.z);
if (xPos <= 50 && zPos <= 50) devuelve true;
return false; }
El estado chase
igualmente mientras el tanque en la persecucin estatal, se podr controlar su dista
ncia con el jugador tanque. Si es lo suficientemente cerca, se cambiar el estado
del ataque. Si el jugador depsito ha ido demasiado lejos, entonces deber regresar
a la Patrulla Estatal.
protected void UpdateChaseState() { // Establecer la posicin de destino como el j
ugador posicin = playerTransform destPos.posicin;
//controlar la distancia con el jugador depsito cuando //la distancia est cerca, l
a transicin al ataque de flotacin del estado dist = Vector3.Distancia(transform.po
sicin, playerTransform.position);
[ 43 ]

Si (dist <= 200.0f) { curState = FSMState.Ataque; } //volver a patrullar es s


er demasiado else if (dist >= 300.0f) { curState = FSMState.patrulla; }
//Avanzar transform.translate(vector3.forward * Tiempo.deltaTime * curSpeed); }
El estado de ataque
si el jugador depsito est lo suficientemente cerca como para atacar a nuestro depsi
to de AI, vamos a girar la torreta objeto al depsito del reproductor y, a continu
acin, empezar a disparar. No regresar a la patrulla estatal, si el jugador depsito
est fuera de rango.
protected void UpdateAttackState() { // Establecer la posicin de destino como el
jugador posicin = playerTransform destPos.posicin;
//Comprobar la distancia con el jugador de flotacin tanque dist = Vector3.Distanc
ia(transform.posicin, playerTransform.position);
if (dist >= 200.0f && dist < 300.0f) { //Girar al punto de destino
Quaternion targetRotation = Quaternion.LookRotation(destPos - transform.posicin)
; transform.rotacin =( Slerp Quaternion.transform.rotacin, targetRotation, tiempo.
deltaTime * curRotSpeed);
//Avanzar transform.translate(vector3.forward * Tiempo.deltaTime * curSpeed);
[ 44 ]

curState = FSMState.Ataque; } //transicin para patrullar el depsito est demasiado l


ejos else if (dist >= 300.0f) { curState = FSMState.patrulla; }
//siempre girar la torreta hacia el jugador Quaternion turretRotation = Quaterni
on.LookRotation(destPos -.La posicin de la torreta);
.la rotacin de la torreta = Quaternion.Slerp(.la rotacin de la torreta, turretRota
tion, Tiempo.deltaTime * curRotSpeed);
//disparar balas ShootBullet(); } private void ShootBullet() { if (elapsedTime s
hootRate >=) { //Disparar la bala instanciar(Vieta bulletSpawnPoint.posicin, bu
lletSpawnPoint.rotacin); = 0.0f elapsedTime; } }
El estado muerto
si el depsito ha alcanzado el estado muerto, tendremos que explotar.
protected void UpdateDeadState() { //Mostrar los muertos animacin con algunos efe
ctos de fsica si (!bDead) { bDead = true; explode(); } }
[ 45 ]

Aqu tienes una pequea funcin que dar un agradable efecto de explosin. Acabamos de apl
icar un
rigidbody ExplosionForce a nuestro componente con algunas direcciones aleatorias
, dada en el cdigo siguiente:
protected void explode() { float rndX = Random.Range(10.0f, 30.0f); float rndZ =
Random.Range(10.0f, 30.0f); para (int i = 0; i < 3; i++) {(10000.0AddExplosi
onForce rigidbody.f, transform.posicin - nuevo Vector3(rndX, 10.0f, rndZ), 40,0f,
10.0f); rigidbody.transform.TransformDirection velocidad =( nuevo Vector3(rndX,
20.0f, rndZ)); }
Destroy(gameObject, 1.5F); }
hacerse dao
si el tanque es alcanzado por una bala, entonces el valor de la propiedad de la
salud sern deducidos, sobre la base de la Bala dao del objeto valor.
void OnCollisionEnter(Colisin colisin) { //reducir la salud si(colisin.gameObject.t
ag == "Bullet") { salud -=colisin.gameObject.GetComponent <Bullet>().el dao; } }
[ 46 ]

puede abrir SimpleFSM.scene en la unidad y, a continuacin, debera ver la AI tanque


s patrullando, perseguir y atacar al jugador. Nuestro jugador el depsito no tiene
daos de AI tanques, as que nunca se destruyen. Pero AI tanques tienen la propieda
d de salud, y daos de las balas del jugador. Por lo tanto, ver su explosin, una vez
que su
propiedad de salud llega a cero.
Tanques de AI en accin
usando una FSM
FSM marco marco vamos a usar aqu est adaptado del FSM C# Framework, que puede ser
encontrado en unifycommunity.com. Ese marco es de nuevo una parte de la mquina de
estados finitos deterministas marco, basado en el captulo 3.1 del Juego de progr
amacin 1 Gemas, por Eric Dybsend. , tan solo estaremos viendo las diferencias ent
re este FSM y el uno que hicimos antes. La FSM completa puede encontrarse con lo
s activos que vienen con el libro. Ahora vamos a estudiar cmo el marco funciona y
cmo usarlo para ejecutar nuestro tanque AI.
La AdvanceFSM y FSMState son las dos clases principales de nuestro marco. Echemo
s un vistazo a ellos.
[ 47 ]

La clase
La clase AdvanceFSM AdvanceFSM bsicamente administra todos los FSMState(s) implem
enta y mantiene actualizado con las transiciones, y el estado actual. As, la prim
era cosa que hacer antes de utilizar nuestro marco es declarar las transiciones
y estados que planeamos implementar para nuestros tanques de AI.
El cdigo en el AdvancedFSM.cs ile es como sigue:
Usando UnityEngine; using System.Collections; using System.Collections.Generic;
transicin de enumeracin pblica { None = 0,,, LostPlayer SawPlayer ReachPlayer, NoHe
alth, }
{ FSMStateID enumeracin pblica Ninguno = 0, el patrullaje, perseguir, atacar, muer
tos, }
tiene un objeto List para almacenar los objetos FSMState y dos variables locales
para almacenar el ID actual de la clase, y FSMState FSMState actual
lista privada. <FSMState>FsmStates; privado FSMStateID currentStateID; pblica FSM
StateID CurrentStateID currentStateID { get { return; } }
[ 48 ]

currentState FSMState privado; pblica FSMState CurrentState { get { return curren


tState; } }
Los mtodos DeleteState AddFSMState y agregar y eliminar las instancias de nuestra
clase FSMState en nuestra lista, respectivamente. Cuando el mtodo se llama Perfo
rmTransition, actualiza la CurrentState variable con el nuevo estado basado en l
a transicin.
La clase FSMState
FSMState gestiona las transiciones a otros estados. Tiene un objeto llamado dicc
ionario mapa
para almacenar los pares clave-valor de transiciones y estados. Por ejemplo, la
transicin SawPlayer asigna a la persecucin estatal y LostPlayer asigna a la patrul
la estatal, y as sucesivamente.
El cdigo en el FSMState.cs ile es como sigue:
Usando UnityEngine; using System.Collections; using System.Collections.Generic;
la clase abstracta FSMState { Diccionario protegida <Transition, FSMStateID>Mapa
= Nuevo diccionario <Transition, FSMStateID>(); ...
Los mtodos DeleteTransition AddTransition y simplemente aadir y eliminar
las transiciones de su diccionario de transicin de estados objeto de mapa. El mtod
o GetOutputState busca en el objeto del mapa, y devuelve el estado basado en la
transicin de entrada.
La clase tambin FSMState declara dos mtodos abstractos que su nio necesita para imp
lementar las clases. Son como sigue:
...
public abstract void razn(Transformar player, transformar npc); public abstract v
oid Act(reproductor de transformacin, transformar npc); ...
[ 49 ]
El mtodo tiene razn para comprobar si el Estado debe hacer la transicin a otro esta
do. Y la ley mtodo realiza la ejecucin efectiva de las tareas para la
variable currentState como moverse hacia un punto de destino y, a continuacin, pe
rseguir o atacar al jugador. Ambos mtodos requieren datos transformados del jugad
or y la entidad de NPC, que puede ser obtenido usando esta clase.
El Estado,
a diferencia de las clases en nuestro ejemplo SimpleFSM anterior, los estados de
nuestro tanque AI se escriben en clases separadas, heredado de la clase como At
tackState FSMState, ChaseState,
DeadState y PatrolState, cada uno de los cuales implementa los mtodos de razonar
y actuar. Echemos un vistazo a la clase PatrolState como ejemplo.
La clase PatrolState
tiene tres mtodos: un constructor, una razn y un acto.
El cdigo en el PatrolState.cs ile es como sigue:
Usando UnityEngine; using System.Collections;
public class PatrolState : FSMState {
public PatrolState(Transform[] wp) { waypoints = wp; stateID = FSMStateID.patrul
las;
curRotSpeed = 1.0f; curSpeed = 100,0 f; }
public void override razn(Transformar player, transformar npc) { // comprobar la
distancia con el jugador depsito //cuando la distancia est cerca, la transicin al e
stado si chase (Vector3.Distancia(npc.posicin, player.posicin) &lt;= 300.0f) { Deb
ug.log("Cambiar a estado Chase");
[ 50 ]

npc.GetComponent <NPCTankController>().SetTransition( Transicin.SawPlayer); } }


public void override Act(reproductor de transformacin, transformar npc) { //busca
r otro punto de patrulla aleatoria si el actual //punto se alcanza
si (Vector3.Distancia(npc.posicin, destPos) &lt;= 100,0 F) { Debug.log("alcanzado
al destino" + point\ncalculating el siguiente punto"); FindNextPoint(); }
//Girar al punto de destino Quaternion targetRotation = Quaternion.LookRotation(
destPos - CNP.position);
CPN.rotacin = Quaternion.Slerp(npc.rotacin, targetRotation, tiempo.deltaTime * cur
RotSpeed);
//Avanzar npc.translate(vector3.forward * Tiempo.deltaTime * curSpeed); } }
El mtodo constructor toma la matriz de puntos de referencia y los almacena en una
matriz local y, a continuacin, se inicializa las propiedades tales como el movim
iento y la velocidad de rotacin. La razn mtodo comprueba la distancia entre s (AI) y
el tanque de depsito de jugador. Si el jugador est en la gama del depsito, se esta
blece la transicin ID para la transicin
SetTransition SawPlayer utilizando el mtodo de la clase NPCTankController que tie
ne el siguiente aspecto:
el cdigo en el NPCTankController.cs ile es como sigue:
public void SetTransition(transicin t) { PerformTransition(t); }
[ 51 ]

Es slo un contenedor de mtodo que llama al mtodo


AdvanceFSM PerformTransition de la clase. Este mtodo actualizar el CurrentState va
riable, con el responsable de esta transicin, con el objeto de transicin, y el est
ado de la transicin desde el objeto de mapa de diccionario FSMState clase. La Ley
mtodo simplemente actualiza la AI del tanque al punto de destino, gira el depsito
en esa direccin, y luego se mueve hacia adelante. Otro estado de clases tambin si
ga esta plantilla con diferentes procedimientos de razonar y actuar. Ya hemos vi
sto en nuestra anterior FSM simples ejemplos, de modo que no vamos a describir a
qu. Vea si puede lustracin cmo establecer estas clases en su propio. Si te quedas a
tascado, los activos que vienen con este libro tendr el cdigo para que usted mire.
La clase NPCTankController
nuestro tanque AI, el NPCTankController clase heredar de AdvanceFSM. De esta form
a podemos configurar los estados de nuestros tanques de NPC:
...
private void ConstructFSM() {
PatrolState patrol = new PatrolState(waypoints); inspeccin.AddTransition(Transicin
.SawPlayer, FSMStateID.persiguiendo); inspeccin.AddTransition(Transicin.NoHealth,
FSMStateID.muertos);
ChaseState chase = new ChaseState(waypoints); chase.AddTransition(Transicin.LostP
layer, FSMStateID.patrullando); chase.AddTransition(Transicin.ReachPlayer, FSMSta
teID.atacar); chase.AddTransition(Transicin.NoHealth, FSMStateID.muertos);
ataque AttackState = new AttackState(waypoints); el ataque.AddTransition(Transic
in.LostPlayer, FSMStateID.patrullando); el ataque.AddTransition(Transicin.SawPlaye
r, FSMStateID.persiguiendo); el ataque.AddTransition(Transicin.NoHealth, FSMState
ID.muertos);
[ 52 ]

DeadState muerto = nuevo DeadState(); dead.AddTransition(Transicin.NoHealth, FSMS


tateID.muertos);
AddFSMState(patrulla); AddFSMState(chase); AddFSMState(ataque); AddFSMState(muer
tos); }
Aqu est la belleza de usar nuestro marco de Micronesia. Puesto que los estados son
auto-gestionados en sus respectivas clases, nuestros NPCTankController clase slo
necesita llamar a los
mtodos de razonar y actuar del actual estado activo. Esto elimina la necesidad de
escribir una larga lista de las if/else y switch, hinchado y cdigo. En lugar de
ello, ahora nuestros miembros estn debidamente empaquetada en las clases de sus p
ropios, haciendo que el cdigo sea ms manejable como el nmero de miembros a implemen
tar y las transiciones entre ellos se vuelven ms y ms complejos en grandes proyect
os.
...
protegidas override void FSMFixedUpdate() { CurrentState.Razn(playerTransform, tr
ansform); CurrentState.Act(playerTransform, transform); }
Esta es, pues, cmo funciona nuestro marco. En resumen, los principales pasos para
utilizar este marco son los siguientes:
1. Declarar las transiciones y estados en la clase AdvanceFSM.
2. Escribir el estado FSMState clases heredadas de la clase y, a continuacin, apl
icar los mtodos de razonar y actuar.
3. Escribir el custom NPC AI Clase heredada de AdvanceFSM.
4. Crear estados de las clases de estado y, a continuacin, agregar la transicin y
estado de pares utilizando el mtodo FSMState AddTransition de la clase.
5. Agregar a esos Estados a la lista estatal de la clase AdvanceFSM, utilizando
el
mtodo AddFSMState.
6. Llame al CurrentState variable mtodos de razonar y actuar en el ciclo de actua
lizaciones del juego.
Puedes jugar con el AdvancedFSM.escena en la unidad. Se ejecutar en la misma form
a que nuestro anterior SimpleFSM ejemplo. Pero ahora el cdigo y las clases estn ms
organizadas y manejables.
[ 53 ]
Resumen
En este captulo, hemos aprendido cmo implementar mquinas de estado en Unity3D basad
a en un simple juego de tanques. Nos irst miraron cmo implementar FSM en la forma
ms sencilla, utilizando las instrucciones switch. A continuacin, estudiamos cmo ut
ilizar un marco para hacer la Ia aplicacin fcil de manejar y extender.
En el prximo captulo, vamos a echar un vistazo a la aleatoriedad y probabilidad y
cmo podemos utilizarlo para hacer que el resultado de nuestros juegos ms impredeci
bles.
[ 54 ]

Al Azar y Probabilidad
En este captulo, vamos a ver cmo los conceptos de probabilidad puede ser aplicado
al juego AI. Este captulo ser ms sobre el juego genrico de tcnicas de desarrollo de A
I en el azar y probabilidad temas y menos acerca de Unity3D en particular.
Adems, pueden aplicarse a cualquier juego el desarrollo de middleware o marco tec
nolgico. Estaremos con el mono C# en Unity3D para las demostraciones principalmen
te utilizando la consola para salida de datos, y no la direccin speciic mucho ace
rca de las caractersticas del motor Unity3D y el propio editor.
Los programadores de juegos utilizan la probabilidad o el factor conidence para
agregar un poco de incertidumbre a los comportamientos de los personajes control
ados por la IA, as como para el mundo del juego. Esto hace que el sistema de inte
ligencia artiicial impredecibles de un cierto resultado, y puede proporcionar a
los jugadores una experiencia ms emocionante y desafiante.
Tomemos un ejemplo tpico de un partido de ftbol. Una de las reglas de un juego de
ftbol es otorgar un tiro libre directo si un jugador est sucia mientras intenta po
seer el baln del rival. Ahora, en lugar de dar un foul y un free kick todo el tie
mpo cada vez que sucede, el juego sucio desarrollador puede aplicar una probabil
idad, de modo que slo el 98 por ciento de todas las faltas sern recompensados con
un tiro libre directo. Como resultado, la mayora de las veces, el jugador recibir
un free kick directa. Pero cuando ese 2% restante pasa, como ha alcanzado el otr
o jugador y sabe que va a ser un tiro libre pero el rbitro pasa, puede proporcion
ar un cierto feedback emocional para los jugadores de ambos equipos (suponiendo
que ests jugando contra otro ser humano).
El otro jugador se siente enfadado y decepcionado, mientras que usted sentira afo
rtunado y satisied. Al final, los rbitros son humanos, y como todos los otros ser
es humanos, pudieran no ser 100% correcta todo el tiempo.
Por lo tanto, usamos la probabilidad en un juego AI para hacer el juego y los pe
rsonajes ms animado y parecen ms realistas, por no hacer la misma decisin o tomar l
a misma accin una y otra vez. Hay muchos temas para discutir y debatir en la prob
abilidad de dominio. As que este pequeo captulo nico slo podr hacer frente a los conce
ptos bsicos, y cmo podemos implementar algunas de ellas en Unity3D.

En este captulo, vamos a ir a travs de azar y probabilidad. Crearemos un sencillo


juego de dados. Tambin daremos algunos ejemplos de aplicaciones de probabilidad y
dynamic AI. Por ltimo, daremos inish el captulo con una simple mquina de ranura, y
luego aadir ms funciones de probabilidad.
Probabilidad aleatoria es bsicamente una medida de cun probable es que una determi
nada condicin o un resultado favorable puede lograrse entre todos los posibles re
sultados, si se selecciona aleatoriamente. Por lo tanto, Hablando de probabilida
d, que uno no se puede descuidar la importancia de la aleatoriedad. La generacin
de nmeros aleatorios (RNG) es muy importante cuando necesitamos producir resultad
os impredecibles. El ms simple y probablemente la ms antigua tcnica sera tirar los d
ados para generar un valor aleatorio entre 1 y 6. Los nmeros aleatorios son produ
cidos informticamente mediante un generador de nmeros pseudoaleatorios (PRNG) y de
terminan la misma secuencia de nmeros aleatorios basados en el valor inicial de s
emilla. Por lo tanto, si queremos conocer tericamente el valor semilla, podemos r
egenerar la misma secuencia de nmeros aleatorios de nuevo, y por lo tanto no son
consideradas como verdaderamente aleatoria. El valor semilla es generalmente gen
erada desde el estado del sistema informtico, como el tiempo transcurrido en mili
segundos desde el equipo comience a funcionar. Algunos RNGs son ms aleatorios que
otros. Si estuvisemos creando un programa de cifrado, queremos mirar hacia una ms
aleatorio RNG. Para los juegos, estaremos haciendo el RNG, que viene con la uni
dad sufice. Ahora veamos cmo podemos generar nmeros aleatorios en Unity3D.
La clase Random Script Unity3D tiene una clase Random para generar datos aleator
ios. Dos de las propiedades ms utilizadas seran la semilla y valor:
static var : semillas int
puede establecer esta propiedad de inicializacin de la clase Random para iniciali
zar el generador de nmeros aleatorios. Normalmente, no queremos sembrar el mismo
valor una y otra vez, ya que esto dar como resultado la misma secuencia predecibl
e de nmeros aleatorios generados.
Uno de los motivos para mantener el mismo valor semilla es para fines de prueba:
static var valor : float
puede leer al azar.propiedad value para obtener un nmero aleatorio entre 0.0 (inc
lusive) y 1.0 (inclusive). Ambos 0.0 y 1.0 puede ser devuelto por esta propiedad
.
Otro mtodo de la clase que podra ser muy til es el mtodo Range.
funcin esttica Gama (min : float, max : float) : float
[ 56 ]

El mtodo Range puede utilizarse para generar un nmero aleatorio a partir de un ran
go. Cuando se da un valor entero, devuelve un nmero entero aleatorio entre MIN y
MAX (inclusive) (exclusivo). Esto significa que un cero puede ser devuelto, pero
nunca un uno. Si pasa en loat valores para la gama, va a devolver un nmero flota
nte aleatorio entre min (inclusive) y MAX (inclusive). Tomar nota del exclusivo
e inclusivo de piezas. Desde el entero valor aleatorio es exclusiva de max en la
gama, tendremos que pasar en n+1 como el rango mximo, donde n es el nmero entero
aleatorio mxima deseada. Sin embargo, para el flotador valor aleatorio, el valor
mximo en la gama es inclusivo.
Juego de dados aleatorio simple
vamos a configurar un juego de dados muy simple en una nueva escena, donde un nme
ro aleatorio que se genera entre uno y seis, y comprueban el valor de entrada. E
l jugador ganar, si el valor de entrada coincide con el resultado de los dados ge
nerados al azar como se muestra en la siguiente DiceGame.cs ile:.
utilizando UnityEngine; using System.Collections;
public class DiceGame : MonoBehavior
inputValue { public string = "1";
nulo OnGUI() { GUI.Etiqueta rect(nuevo (10, 10, 100, 20), "Entrada: "); inputVal
ue = GUI.TextField(nuevo rect(120, 10, 50, 20), 25) inputValue; si (GUI.Button(n
uevo rect(100,50,50,30),"Play") { Debug.log("tirada de dados..."); Debug.log("ha
llazgo aleatorio entre 1 a 6..."); int diceResult = Random.Range(1,7); Debug.log
("Resultado: " + diceResult); if (diceResult ==.Parse(int)) { guiText inputValue
.Text = "DADOS RESULTADO: " + diceResult.ToString() + "\r\nque GANAR!"; } else {
guiText.Text = "DADOS RESULTADO: " + diceResult.ToString() + "\r\nno PERDER!";
} } } }
[ 57 ]

debemos aplicar este simple juego de dados en el OnGUI() Mtodo que queremos repre
sentar algunos de los controles de la interfaz grfica de usuario, como una etique
ta, un texto ield para introducir el valor de entrada, y un botn para reproducir.
La guiText objeto se utilizar para mostrar el resultado. Agregar un guiText a la
escena, vaya a Juego | Objeto crear otros | GUI texto y agregar nuestro script
al objeto. Los resultados que se obtienen si ejecuta el juego se muestra en la s
iguiente captura de pantalla:
simple juego de dados los resultados
es un puro juego de azar, y no existe ninguna probabilidad modiied involucrados.
A cada lado de la superficie de los dados tiene la misma oportunidad de ser ele
gido.
Deinition de probabilidad,
hay muchas maneras de deine probabilidad basado en las situaciones y en el conte
xto del dominio. Los ms comnmente utilizados nocin de probabilidad se refieren a la
posibilidad de que un evento ocurra correctamente. La probabilidad de que un ev
ento ocurra es normalmente escrito como P(A). Para calcular P(A) necesitamos sab
er el nmero de formas o veces puede ocurrir
(n), y el nmero total de veces que todos los dems posibles eventos pueden ocurrir
(N).
As que la probabilidad de que un evento puede ser calculada como
P(A) = n / N
P(A) es la probabilidad de que un evento ocurra, y es igual a la cantidad de for
mas en que puede ocurrir (n) fuera del nmero de todos los resultados (N). Si P(A)
es la probabilidad de que un evento ocurra exitosamente, entonces la probabilid
ad de un evento no ocurrir, o la probabilidad de fracaso de un evento es igual a:
(A) Pf = 1 - P.(A)
El rango de probabilidad es un nmero decimal de cero a uno. Probabilidad de cero
significa que no hay oportunidad para el evento deseado a ocurrir, y uno de los
medios que es 100% segura para que se produzca el evento. Y P(A) + Pf (A) debe s
er igual a uno. Desde los valores de probabilidad van de cero a uno, podemos obt
ener el valor porcentual multiplicando por 100.
[ 58 ]

independiente y eventos relacionados


otro importante concepto de probabilidad es si la probabilidad de que ocurra un
evento en particular depende de cualquier otro evento o no en algunos aspectos.
Por ejemplo, lanzando una de seis caras dados dos veces son dos eventos independ
ientes. Cada vez que se lanza un dado, la probabilidad de cada lado para subir e
s una sexta parte. Por otro lado, el dibujo de dos cartas de la misma baraja son
dos eventos relacionados. Si se dibujara un gato en el irst evento, hay menos p
robabilidad de que usted puede obtener otro Jack en el segundo caso.
Probabilidad condicional
al lanzar dos dados de seis caras al mismo tiempo, cul es la probabilidad de conse
guir un tanto en los dados? Aqu hay dos eventos condicional; para obtener uno en
el irst dados, y tambin para conseguir una en la segunda tirada. Ellos dependen u
nos de otros para calcular la probabilidad de obtener uno en ambos los dados. La
probabilidad de conseguir una en el irst dados es un sexto, y tambin para el seg
undo dados es una sexta parte. Por lo tanto, la respuesta sera un sexto veces un
sexto que es 1/36, o un 2,8 por ciento de probabilidad.
Ahora veamos otro ejemplo, cul es la probabilidad de que la suma de los nmeros se m
uestran en dos dados es igual a dos? Puesto que slo hay una manera de conseguir e
sta suma, que es uno y uno, la probabilidad sigue siendo la misma que obteniendo
el mismo nmero en ambos dados. En ese caso sera an 1/36.
Pero acerca de cmo la suma de los nmeros que se muestran en los dos dados a siete?
Como puede ver, hay un total de seis posibilidades para obtener un total de sie
te, a partir de la siguiente tabla:
Dados los Dados 1 2
1 6 2 5 3 4 4 3 5 2 6 1 de
modo que la probabilidad de obtener una suma de siete a dos dados es 6/36 o 1/6,
que es del 16,7 por ciento. Estos son algunos ejemplos de probabilidad condicio
nal, donde dos acontecimientos dependen unos de otros para lograr un resultado d
eseable.
[ 59 ]

Un dados cargados
Ahora, supongamos que no hemos sido honestos, y nuestros dados es cargado, de fo
rma que el lado del nmero seis tiene una doble oportunidad de desembarque hacia a
rriba. Durante un perodo de seis caras de los dados, la probabilidad de cada lado
mirando hacia arriba es aproximadamente una sexta parte (0,17).
Ya hemos duplicado la posibilidad de obtener seis, necesitamos el doble de proba
bilidad de tener seis, digamos hasta 0,34. Y la probabilidad de que el IVE lados
restantes sern reducidos a 0.132.
La manera ms simple de implementar este algoritmo dados cargados es generar un va
lor aleatorio entre 1 y 100. Compruebe si el valor aleatorio es en un rango de 1
a 35. Si es as volver 6, de lo contrario, obtenga un valor de dados al azar entr
e uno y ive, ya que estos valores tienen la misma probabilidad de 0.13.
As que aqu est nuestra throwLoadedDice() Mtodo:
int() { throwDiceLoaded Debug.log("tirada de dados..."); int randomProbability =
Random.Range(1101); int diceResult = 0; Si (randomProbability &lt; 36) { diceRe
sult = 6; } else { diceResult = Random.Range(1,5); } Debug.log("Resultado: " + d
iceResult); return diceResult; }
Si queremos probar nuestro nuevo algoritmo dados cargados por tirar los dados va
rias veces, ver que el valor 6 da ms de lo habitual. Aqu est nuestra nueva OnGUI():
void OnGUI() { GUI.Etiqueta rect(nuevo (10, 10, 50, 20), "Entrada: "); inputValu
e = GUI.TextField(nuevo rect(60, 10, 50, 20), inputValue, 25); si (GUI.Button(nu
evo rect(60,40,50,30),"Play") { int totalSix = 0; for (int i=0;i&lt;10;i++) { in
t = throwDiceLoaded diceResult(); if (diceResult totalSix == 6)++; si (diceResul
t ==.Parse(int)) { guiText inputValue.Text = "DADOS RESULTADO: " + diceResult.To
String()+"\r\nque GANAR!"; }

else { [ 60 ] guiText.Text = "DADOS RESULTADO: " + diceResult.ToString()+"\r\nno


PERDER!"; } } Debug.log("total de seis: " + totalSix.ToString(); } }
nos tira los dados diez veces en nuestro OnGUI(), mtodo, y aqu tengo 6 al menos do
s o tres veces (que es aproximadamente el 33 por ciento de diez veces). Pero, si
usted normalmente tirar los dados sin ninguna probabilidad cargado es ms posible
que usted no pueda obtener 6 en absoluto. Tenga en cuenta que el valor 6 es slo
favoreca el 35 por ciento y, por tanto, todava hay una posibilidad de que usted nu
nca tendr un 6 fuera de 10 lanza los dados, aunque es bastante improbable.
Personalidades de carcter
tambin podemos utilizar diferentes probabilidades para especificar el juego de ca
racteres' especialidades.
Supongamos que hemos diseado una propuesta de juego para un juego de gestin de pob
lacin para el gobierno local. Necesitamos abordar y simular las cuestiones como l
a fiscalidad global frente a la atraccin del talento, la inmigracin frente a la co
hesin social, y as sucesivamente. Tenemos tres tipos de caracteres en nuestra prop
uesta, es decir, trabajadores, cientficos y profesionales.
Su eficiencies en la realizacin de las tareas particulares son deined en la sigui
ente tabla:
Caracteres de I+D de construccin Trabajos Empresariales
trabajador cientfico 3 95 2 5 85 10
10 80 10 profesionales
veamos cmo podemos aplicar esta mecnica. Digamos que el jugador necesita para cons
truir nuevas casas para acomodar el aumento de la poblacin. Una casa construccin r
equerira 1.000 unidades de carga a inish. Utilizamos el valor speciied anteriorme
nte como la carga de trabajo que puede ser realizado por segundo por cada tipo d
e unidad para una tarea particular. As que si usted est construyendo una casa con
un trabajador que slo tardar unos 10 segundos en inish la construccin (1000/95), mi
entras que te llevar ms de tres minutos si usted est tratando de construir con los
cientficos (1000/5 = 200 segundos). Lo mismo ser cierto para otras tareas como, po
r ejemplo, R&amp;D y trabajos empresariales. Estos factores se pueden ajustar/ p
osteriormente mejorada a medida que avanza el juego, haciendo que algunas de las
primeras tareas del nivel se vuelven ms sencillas, y tarda menos tiempo.
[ 61 ]

Luego introducimos elementos especiales que pueden ser detectados por el tipo co
ncreto de unidad. Ahora, no queremos dar estos elementos cada vez que una unidad
en particular ha hecho sus tareas. En lugar queremos recompensar al jugador com
o una sorpresa. As asociamos la probabilidad de encontrar tales elementos segn el
tipo de unidad, tal como se describe en la siguiente tabla:
artculos especiales trabajador profesional cientfico de las materias primas 0.3 0.
1 0.0
New Tech 0.0 0.3 0.0
0.1 0.2 0.4
La bonificacin tabla anterior significa que hay un 30% de probabilidad de que un
trabajador se ind algunas materias primas, y un 10 por ciento de probabilidades
de ganar ingresos extra siempre han construido una fbrica o una casa. Esto permit
e a los jugadores para anticipar las posibles futuras recompensas, una vez que h
an realizado algunas tareas. Esto puede hacer que el juego sea ms divertido porqu
e los jugadores no conocern el resultado del evento.
FSM con probabilidad
discutimos las mquinas de estado finito (FSM) en el Captulo 2, mquinas de estado fi
nito, utilizando tanto las declaraciones de switch simple as como mediante el mar
co de Micronesia. La decisin de elegir qu estado desea ejecutar era puramente basa
do en el valor verdadero o falso de una determinada condicin. Recuerde las siguie
ntes FSM de nuestro depsito controlados por la IA entidad?
Depsito FSM AI
[ 62 ]

Para hacer la IA ms interesante, y un poco impredecible, podemos dar nuestro tanq


ue entidad algunas opciones con probabilidades para elegir, en lugar de hacer la
misma cosa cuando se cumple una determinada condicin. Por ejemplo, en nuestra an
terior FSM, nuestro depsito de AI se persiga el jugador depsito una vez que el jug
ador est en su lnea de visin. En su lugar, podemos dar nuestro AI otro estado, como
lee con alguna probabilidad como un 50 por ciento como se muestra en el siguien
te grfico:
FSM con probabilidad
ahora en lugar de perseguir cada vez, AI manchas del depsito el jugador; hay un 5
0 por ciento de probabilidades de que te lee, y tal vez informe a la sede o algo
as. Podemos aplicar esta mecnica de la misma manera en que lo hicimos con nuestro
anterior ejemplo de dados. Primero necesitamos generar un valor aleatorio entre
1 y 100, y ver si el valor se encuentra entre uno y 50 o 51 y 100. (o podemos e
legir aleatoriamente entre cero y uno.) y, a continuacin, elija un estado en cons
ecuencia. La otra forma de implementar esto es mal una matriz con estas opciones
en proporcin a sus respectivas probabilidades. A continuacin, escoja un estado al
eatorio de esta piscina como si estuviera dibujando un ganador de la lotera. Vamo
s a ver cmo utilizar esta tcnica, tal como se muestra en la siguiente FSM.cs ile:
utilizando UnityEngine; using System.Collections;
public class FSM : enumeracin pblica FSMState MonoBehavior { { Chase, huir }
public int chaseProbabiilty = 50; public int fleeProbabiilty = 50;
//un sondeo para almacenar los estados segn su //probabilidades public ArrayList
statesPoll = new ArrayList();
[ 63 ]

void Inicio () { //llenar la matriz para (int i = 0; i &lt; chaseProbabiilty; i+


+) { statesPoll.Add(FSMState.Chase); } for (int i = 0; i &lt; fleeProbabiilty; i
++) { statesPoll.Add(FSMState.huir); } }
void OnGUI() { if (GUI.Button(nuevo rect(10,10,150,40), "Player on Sight") { int
randomState = Random.Range(0, statesPoll.Count); Debug.log(statesPoll[randomSta
te].ToString(); } } }
en nuestra OnGUI(), mtodo que, al hacer clic en el Botn del ratn, acabamos de elegi
r un elemento aleatorio de nuestro statesPoll matriz. Obviamente, el uno con ms e
ntradas en la encuesta tienen una mayor probabilidad de ser seleccionadas. Prubel
o.
Dynamic AI
tambin podemos utilizar la probabilidad para especificar los niveles de inteligen
cia de personajes controlados por la IA, y el global game settings. Esto a su ve
z puede afectar el nivel de dificultad general del juego, y mantener la dificult
ad y lo suficientemente interesante como para los jugadores. Como se describe en
el libro, el arte del diseo de juegos, Jesse Schell, Morgan Kaufmann publicacion
es, los jugadores slo continuar nuestro juego si queremos mantenerlos en su canal
bajo.
El Canal de flujo
[ 64 ]

Los jugadores se sientan ansiosos y se decepciona si presentamos retos difciles p


ara solucionar antes de que tengan las habilidades necesarias. Por otra parte, u
na vez que domines las habilidades, y si queremos seguir el juego al mismo ritmo
, entonces no se aburrir. La zona gris que puede mantener los jugadores contratad
os por un tiempo largo es entre estos dos extremos de duro y fcil, que el autor o
riginal conocido como el canal bajo. Para mantener a los jugadores en el canal b
ajo, los diseadores de juegos necesitan para alimentar a los retos y misiones que
coinciden con la progresiva habilidades que los jugadores han adquirido con el
paso del tiempo. Sin embargo, no es una tarea fcil para ind un valor que funciona
para todos los jugadores, ya que el ritmo de aprendizaje y las expectativas pue
den ser diferentes en forma individual.
Una forma de abordar este problema es recoger el jugador intentos y resultados d
urante las sesiones de juego, y para ajustar la probabilidad del oponente AI en
consecuencia. Aunque este enfoque se supone que ayudar a que los juegos sean ms at
ractivas, hay muchos otros jugadores a quienes no les gusta este enfoque, puesto
que este mtodo quita el orgullo y la satisfaccin de inishing un duro juego. Despus
de todo, vencer a un muy duro boss AI carcter a pesar de todos estos retos puede
n ser mucho ms gratificante y satisfactoria que ganar el juego porque la AI es to
nto. Se sentiran mucho peor si ellos ind que la IA se vuelve tonto porque no tien
en suficientes habilidades para coincidir. Por lo tanto, debemos ser cuidadosos
acerca de cundo queremos aplicar esta tcnica en nuestros juegos.
Mquina de ranura de demostracin
en este inal demo, vamos a disear e implementar un juego de la mquina de ranura co
n 10 smbolos y tres tambores. Para hacerlo ms simple, utilizaremos los nmeros de ce
ro a nueve como nuestros smbolos. Muchas mquinas de ranura podra utilizar formas de
fruta y otras formas sencillas, como campanas, estrellas y letras. Algunas otra
s mquinas tragaperras suelen utilizar un tema speciic basados en pelculas o progra
mas de televisin populares como una franquicia. Ya hay 10 smbolos y tres tambores,
que es un total de 1.000 (10^3) combinaciones posibles.
Esta mquina de ranura aleatorios azar slot machine demo es similar a nuestro ante
rior ejemplo de dados. Esta vez vamos a generar tres nmeros aleatorios de tres ta
mbores. El pago solamente ser cuando usted consigue tres de los mismos smbolos en
la lnea de pago. Para simplificarlo, haremos slo tienen una lnea para jugar contra
ellos en esta demostracin. Y si el jugador gana, el juego volver a 500 veces la ca
ntidad apostada.
[ 65 ]

configuraremos nuestra escena con cuatro objetos de texto de GUI para representa
r los tres tambores y el mensaje de resultado.
Nuestro GUI objetos de texto
esta es la forma en que nuestro nuevo script mira, como se muestra en la siguien
te SlotMachine.cs ile:
utilizando UnityEngine; using System.Collections;
public class SlotMachine : MonoBehavior {
flotacin pblica spinDuration = 2.0f; public int numberOfSym = 10; privado GameObje
ct betResult;
privados bool startSpin = false; privados bool firstReelSpinned = false; privado
s bool secondReelSpinned = false; privados bool thirdReelSpinned = false;
cadena privada betAmount = "100";
private int firstReelResult = 0; int privado secondReelResult = 0; int privado t
hirdReelResult = 0;
privados de flotacin = 0.0f elapsedTime;
//Utilizar esto para inicializacin void Inicio () { betResult = gameObject; betRe
sult.guiText.Text = ""; }
[ 66 ]

void OnGUI() { GUI.Label(nuevo rect(200, 40, 100, 20), "La apuesta: "); betAmoun
t = GUI.TextField(nuevo rect(280, 40, 50, 20), betAmount, 25); si (GUI.Button(nu
evo rect(200, 300, 150, 40), "Tirar" de hgado) { Start(); startSpin = true; } }
void checkBet() { if (firstReelResult == secondReelResult &amp;&amp; secondReelR
esult == thirdReelResult) { betResult.guiText.Text = "USTED GANA!"; } else { bet
Result.guiText.Text = "perders!"; } }
//Update se llama una vez en cada fotograma vaco FixedUpdate () { if (startSpin)
{ elapsedTime Tiempo +=.deltaTime; int randomSpinResult = Random.Range(0, number
OfSym); if (!firstReelSpinned) { GameObject.Find("firstReel").guiText.Text = ran
domSpinResult.ToString(); if (elapsedTime spinDuration &gt;=) { firstReelResult
= randomSpinResult; firstReelSpinned = true; elapsedTime = 0; } } else if (!seco
ndReelSpinned) { GameObject.Find("secondReel").guiText.Text = randomSpinResult.T
oString(); if (elapsedTime spinDuration &gt;=) { secondReelResult = randomSpinRe
sult; secondReelSpinned = true; elapsedTime = 0; }
[ 67 ]

} else if (!thirdReelSpinned) { GameObject.Find("thirdReel").guiText.Text = rand


omSpinResult.ToString(); Si (elapsedTime spinDuration &gt;=) { thirdReelResult =
randomSpinResult; startSpin = false; elapsedTime = 0; firstReelSpinned = false;
secondReelSpinned = false; checkBet(); } } } } }
aadir el script a nuestra betResult guiText objeto y, a continuacin, colocar el el
emento guiText en la pantalla. Tenemos un botn llamado tirar de la palanca en el
OnGUI(), mtodo que establecer el lag startSpin true cuando se hace clic en l. Y en
nuestro FixedUpdate() mtodo podremos generar un valor aleatorio para cada carrete
si el startSpin es true. Por ltimo, una vez que tenemos el valor para el tercer
carrete, entonces debemos restablecer el startSpin en false.
Mientras estamos obteniendo el valor aleatorio para cada carrete, tambin podemos
mantener un seguimiento de cunto tiempo ha transcurrido desde que el jugador tira
la palanca. Generalmente en el mundo real, las mquinas tragaperras, cada carrete
tendra tres a ive segundos antes de aterrizar el resultado.
Por lo tanto, tambin estamos tomando algn tiempo en spinDuration speciied antes de
mostrar el ltimo valor aleatorio. Si usted juega la escena y haga clic en el botn
de la palanca de tiro, usted debe ver el ltimo resultado como se muestra en la s
iguiente captura de pantalla:
juego tragaperras aleatorio en accin
[ 68 ]

Desde su probabilidad de ganar es uno de los 100, se vuelve aburrido como usted
pierde varias veces consecutivas. Y, por supuesto, si alguna vez has jugado con
una mquina tragamonedas, esto no es cmo funciona o, al menos, no ms. Normalmente pu
ede haber varias victorias durante su juego. Aunque estas pequeas victorias no re
cuperar su apuesta principal y, a largo plazo, la mayora de los jugadores ir a la
quiebra, las mquinas tragaperras hara ganar ganar grficos y sonidos, lo que los in
vestigadores denominan prdidas disfrazado de WINS.
As que en lugar de una sola forma de ganar-ganar el jackpot-nos gustara modificar
las reglas un poco para que se paga con menor rendimiento durante la sesin de jue
go.
Probabilidad ponderada
real las mquinas tragaperras tienen algo llamado Paytable y tiras del molinete (P
ARS) hoja, que es como el documento de diseo completo de la mquina. El PARS hoja s
e utiliza para especificar cul es el porcentaje de pagos es, cules son los patrone
s ganadores y cules son sus premios, y as sucesivamente. Obviamente el nmero del pa
go de premios y de las frecuencias de esos triunfos deben ser cuidadosamente sel
eccionados, de modo que la casa (slot machine) puede recoger la fraccin de las ap
uestas a lo largo del tiempo, mientras asegurndose a devolver el resto de los jug
adores para hacer la mquina atractiva para jugar. Esto se conoce como porcentaje
de amortizacin o volver al jugador (RTP). Por ejemplo, una mquina de ranura con un
90 por ciento de la RTP significa que con el tiempo la mquina devolver un promedi
o de 90 por ciento de todas las apuestas de los jugadores.
En esta demostracin, no vamos a centrarnos en la eleccin de los valores ptimos de l
a casa para producir speciic gana ms tiempo ni mantener un determinado porcentaje
de amortizacin, sino demostrar la probabilidad de ponderacin speciic smbolos, de m
odo que aparezcan ms veces de lo habitual. As que digamos que nos gustara hacer apa
recer el smbolo de cero a 20 por ciento ms que por casualidad en el irst y tercer
tambor y devolver un pequeo pago de la mitad de la apuesta. En otras palabras, el
jugador slo pierde la mitad de su apuesta si tienen cero smbolos en la primera y
tercera tambores, esencialmente disfrazar una prdida como una pequea victoria.
Actualmente, el smbolo de cero tiene una probabilidad de 1/10 (0.1) o 10 por cien
to de probabilidad de ocurrir. Ahora vamos a hacer que el 30% de cero a la tierr
a en la primera y tercera tambores como se muestra en la siguiente SlotMachineWe
ighted.cs ile:
utilizando UnityEngine; using System.Collections;
public class SlotMachineWeighted : MonoBehavior { flotacin pblica spinDuration = 2
.0f; public int numberOfSym = 10; GameObject betResult pblicos;
privados bool startSpin = false; privados bool firstReelSpinned = false;
[ 69 ]

private bool secondReelSpinned = false; privados bool thirdReelSpinned = false;


private int betAmount = 100;
private int creditBalance = 1000; privado ArrayList weightedReelPoll = new Array
List(); int privado zeroProbability = 30;
int privado firstReelResult = 0; int privado secondReelResult = 0; int privado t
hirdReelResult = 0;
privados de flotacin = 0.0f elapsedTime;
nuevas declaraciones de variables se agregan, como zeroProbability para especifi
car El porcentaje de probabilidad del smbolo de cero a la tierra en la primera y
tercera tambores. La
matriz weightedReelPoll lista se utilizar para enfermos con todos los smbolos (de
cero a nueve) de acuerdo a su distribucin, de forma que podamos posteriormente un
a seleccin al azar de las urnas, como lo hicimos en nuestra anterior FSM ejemplo.
Y luego inicializamos la lista en nuestro mtodo start(), como se muestra en el s
iguiente cdigo:
void Inicio () { betResult = gameObject; betResult.guiText.Text = ""; for (int i
= 0; i &lt; zeroProbability; i++) { weightedReelPoll.Add(0); } nt remainingValu
esProb = (100 - zeroProbability)/9; para (int j = 1; j &lt; 10; J++) { for (int
k = 0; k &lt; remainingValuesProb; k++) { weightedReelPoll.Add(j); } } }
void OnGUI() { GUI.Label(nuevo rect(150, 40, 100, 20), "La apuesta: "); betAmoun
t = int.Parse(GUI.TextField(nuevo rect(220, 40, 50, 20), betAmount.ToString(), 2
5); GUI.Label(nuevo rect(300, 40, 100, 20), "Crditos: " + creditBalance.ToString(
)); if (GUI.Botn(nuevo rect(200,300,150,40)", tire de la palanca") { betResult.gu
iText.Text = ""; startSpin = true; } }
[ 70 ]

y la siguiente es la revisin de nuestra checkBet() Mtodo. En lugar de slo uno gana


el bote, estamos considerando ahora ive condiciones: jackpot, prdida disfrazado c
omo win, near miss, cualquiera de los dos smbolos emparejados en la primera y ter
cera fila, y por supuesto la pierden su condicin:
void checkBet() { if (firstReelResult == secondReelResult &amp;&amp; secondReelR
esult == thirdReelResult) { betResult.guiText.Text = "bote!"; * betAmount credit
Balance += 50; } else if (firstReelResult ==0 &amp;&amp; thirdReelResult ==0) {
betResult.guiText.Text = "GANA" + (betAmount/2).ToString(); -= (betAmount credit
Balance/2); } else if (firstReelResult == secondReelResult) { betResult.guiText.
Text = "AWW... Casi el bote!"; } else if (firstReelResult == thirdReelResult) {
betResult.guiText.Text = "GANA" + (betAmount*2).ToString(); (betAmount creditBal
ance -=*2); } else { betResult.guiText.Text = "perders!"; creditBalance -= betAmo
unt; } }
en el checkBet(), mtodo, hemos diseado nuestra mquina de ranura para volver 50 vece
s si se consigue el jackpot, slo para perder el 50 por ciento de su apuesta, si l
a primera y la tercera los tambores son cero, y dos veces si la primera y tercer
a tambores coinciden con cualquier otro smbolo. Y queremos generar valores para l
os tres tambores en la FixedUpdate() mtodo como se muestra en el siguiente cdigo:
void FixedUpdate () { if (!startSpin) { return; } elapsedTime Tiempo +=.deltaTim
e; int randomSpinResult = Random.Range(0, numberOfSym); if (!firstReelSpinned) {
GameObject.Find("firstReel").guiText.Text = randomSpinResult.ToString(); if (el
apsedTime spinDuration &gt;=) { int weightedRandom = Random.Range(0, weightedRee
lPoll.Count); GameObject.Find("firstReel").guiText.Text =
[ 71 ]

[weightedRandom weightedReelPoll].ToString(); firstReelResult = (int)weightedRee


lPoll[weightedRandom]; firstReelSpinned = true; elapsedTime = 0; } } else if (!s
econdReelSpinned) { GameObject.Find("secondReel").guiText.Text = randomSpinResul
t.ToString(); if (elapsedTime spinDuration &gt;=) { secondReelResult = randomSpi
nResult; secondReelSpinned = true; elapsedTime = 0; } }
para el irst molinete, durante el perodo de hilado, realmente nos muestran los ve
rdaderos valores aleatorios. Pero una vez que el tiempo, elegimos el valor de nu
estra encuesta que ya est llena con smbolos segn las distribuciones de probabilidad
. As nuestro smbolo cero tendra un 30 por ciento ms de probabilidad de ocurrencia qu
e el resto, como se muestra en la siguiente captura de pantalla:
Prdida disfrazado como ganar
realmente el jugador pierde su apuesta, si consigues dos smbolos de cero en la pr
imera y tercera del molinete. Pero nos hacen parecer como una victoria. Es simpl
emente un cojo el mensaje aqu, pero si se puede combinar con buenos grficos; quiz c
on ireworks y agradables efectos de sonido ganadora, esto realmente puede funcio
nar, y atraer a los jugadores apostar ms, y tirar de la palanca una y otra vez.
[ 72 ]

Near miss
si la primera y la segunda los tambores devolver el mismo smbolo, entonces tenemo
s que proporcionar el near miss efecto a los jugadores devolviendo el valor alea
torio en el tercer tambor cerca del segundo. Podemos hacer esto mediante la comp
robacin de la tercera tirada aleatorio resultado IRST. Si el valor aleatorio es l
a misma que la primera y la segunda los resultados, entonces se trata de un bote
, y no debemos alterar el resultado. Pero si no lo es, entonces deberamos modific
ar el resultado de forma que est lo suficientemente cerca de los otros dos. Revis
ar los comentarios en el cdigo siguiente:
else if (!thirdReelSpinned) { GameObject.Find("thirdReel").guiText.Text = random
SpinResult.ToString(); if (&lt; spinDuration elapsedTime) { return; } si ((first
ReelResult == secondReelResult) &amp;&amp; randomSpinResult !=) { randomSpinResu
lt firstReelResult = firstReelResult - 1; Si (randomSpinResult &lt; = firstReelR
esult randomSpinResult firstReelResult) - 1; Si (randomSpinResult &gt; randomSpi
nResult firstReelResult firstReelResult) = + 1; en el caso de (0) randomSpinResu
lt randomSpinResult &lt; = 9; si (9) randomSpinResult randomSpinResult &gt; = 0;
GameObject.Find("thirdReel").guiText.Text = randomSpinResult.ToString(); thirdR
eelResult = randomSpinResult; } else { int weightedRandom = Random.Range(0, weig
htedReelPoll.Count); GameObject.Find("thirdReel").guiText.Text = weightedReelPol
l[weightedRandom].ToString(); thirdReelResult = (int)weightedReelPoll[weightedRa
ndom]; } startSpin = false; elapsedTime = 0; firstReelSpinned = false; secondRee
lSpinned = false; checkBet(); } } }
[ 73 ]

y si esa "near miss" ocurre, usted debe ver como se muestra en la La siguiente c
aptura de pantalla:
near miss
podemos ir an ms lejos, ajustando la probabilidad en tiempo real basado en la cant
idad de la apuesta. Pero eso sera demasiado escalofriante. Otra cosa que podramos
aadir a nuestro juego es una comprobacin para asegurarse de que el jugador no pued
e apostar ms dinero del que ya tienen. Tambin, podramos aadir un juego ms mensaje que
aparecer cuando el jugador ha apostado todo su dinero.
Resumen
En este captulo, hemos aprendido sobre las aplicaciones de la probabilidad en el
juego ai design. Hemos experimentado con algunas de las tcnicas aplicndolas en Uni
ty3D. Como bonificacin, tambin hemos aprendido acerca de los fundamentos de cmo fun
ciona una mquina tragaperras, y aplicado un simple juego de la mquina de ranura co
n Unity3D. Probabilidad en el juego AI se trata de hacer el juego y los personaj
es parecen ms realistas agregando cierta incertidumbre, de modo que los jugadores
no pueden predecir algo seguro. Uno de los usos comunes y deinitions de probabi
lidad es medir la posibilidad de un evento deseado a ocurrir fuera de todos los
otros posibles eventos. Una buena referencia para estudiar ms a fondo las tcnicas
avanzadas de probabilidad en el juego AI, como la toma de decisiones bajo incert
idumbre usando tcnicas Bayesianas, sera la AI para los desarrolladores de juegos,
David M. Bourg, Glenn Seeman, O'Reilly. En el prximo captulo, vamos a echar un vis
tazo a la aplicacin de sensores, y cmo pueden ser utilizados para hacer nuestra AI
consciente de sus alrededores.
[ 74 ]

Aplicacin de sensores
Este es otro breve captulo sobre cmo implementar IA comportamientos utilizando el
concepto de un sistema sensorial, similar a lo que las entidades vivientes. Como
hemos comentado anteriormente, un personaje AI sistema necesita tener concienci
a de su entorno, la conciencia como donde los obstculos son, cuando el enemigo es
t buscando es, si el enemigo est visible en la vista del jugador, y otros. La cali
dad de nuestra inteligencia artiicial NPCs depende por completo de la informacin
que puede obtener del medio ambiente. Sobre la base de esa informacin, los caract
eres AI decidir qu lgica para ejecutar. Si no hay suficiente informacin para la AI,
nuestros caracteres AI pueden mostrar comportamientos extraos, como elegir los lu
gares equivocados para tomar la cubierta, ralent, bucles y extraas acciones y sin
saber qu decisin tomar. Bsqueda de "AI glitch" en YouTube, y te ind algunos comport
amientos de divertidos personajes controlados por la IA incluso en juegos AAA.
Podemos detectar todos los parmetros ambientales y verificar contra nuestros valo
res predeterminados si queremos. Pero con un buen patrn de diseo nos ayudar a mante
ner el cdigo y, por lo tanto, ser fcil de extender. Este captulo presentar tal un pat
rn de diseo que podemos utilizar para implementar los sistemas sensoriales. Vamos
a ir ms de lo que es un sistema sensorial, y cmo hacer que un sistema semejante en
la unidad. A continuacin, vamos a crear una demo donde podemos ver nuestro siste
ma sensorial en accin.

Los sistemas sensoriales bsicos


la AI sistemas sensoriales emular los sentidos como las perspectivas, sonidos e
incluso olores para rastrear e identificar objetos. En el juego AI sistemas sens
oriales, los agentes tendrn que examinar el entorno y verificar esos sentidos per
idicamente sobre la base de su particular inters.
El concepto de un sistema sensorial bsica es que habr dos componentes: Aspecto y s
ensacin. Nuestros caracteres AI tendr sentidos, tales como la percepcin, el olfato
y el tacto. Estos sentidos se busque speciic aspectos tales como enemigo y bando
lero. Por ejemplo, usted podra tener un guardia de patrulla AI con un sentido de
percepcin que est buscando otros objetos del juego con un aspecto del enemigo. O p
odra ser una entidad de zombis con un olor sentido buscando otras entidades con u
n aspecto deined como cerebro.
Para nuestra demostracin, esto es bsicamente lo que vamos a implementar: un interf
az de base llamado sentido que ser implementado por otros sentidos personalizados
. En este captulo, vamos a aplicar la perspectiva y tocar los sentidos. Perspecti
va es lo que los animales usan para ver el mundo que les rodea. Si nuestro perso
naje AI ve un enemigo, queremos ser notiied a fin de que podamos tomar alguna ac
cin. Asimismo, con el tacto, cuando un enemigo se acerca demasiado, queremos ser
capaces de sentir que, casi como si nuestro personaje AI puede or que el enemigo
est cerca. A continuacin, escribiremos una clase de aspecto minimalista que nuestr
os sentidos estarn buscando.
La lluvia{1} es un plugin para AI Unity3D que admite tal sistema sensorial con n
o mucho la codificacin requerida.
La siguiente cita de la lluvia ha sido tomado del producto Http://rivaltheory.co
m/:
lluvia eleva el listn de la AI en la unidad dando personajes la habilidad de perc
ibir el mundo, pathind, ejecutar sofisticado comportamiento rboles y modificar ac
ciones basadas en los rasgos de personalidad. Todo esto puede lograrse con poca
o ninguna experiencia en codificacin.
Configuracin de escena
Comencemos estableciendo nuestra escena. En primer lugar vamos a crear unas pare
des para bloquear la lnea de visin desde nuestro carcter de AI para el enemigo. Est
os ser corta pero amplia los cubos agrupados bajo un objeto llamado juegos vaca ob
stculos. A continuacin, aadimos un plano para ser utilizado como loor. A continuacin
, aadimos una luz direccional, de modo que podemos ver lo que est sucediendo en nu
estra escena.
[ 76 ]

estaremos yendo en esta parte siguiente en detalle a lo largo de todo el captulo,


pero bsicamente, utilizaremos un modelo de tanque sencillo para nuestro jugador,
y un simple cubo para nuestro carcter de AI. Tambin tendremos un objeto de destin
o para mostrarnos donde el tanque se mover en nuestra escena. Nuestra jerarqua de
escena ser similar a la siguiente captura de pantalla:
cmo nuestros hiearchy est configurado
ahora vamos a colocar el depsito, AI, y paredes de caracteres al azar alrededor e
n nuestra escena. Aumentar el tamao del avin a algo que se ve bien. Afortunadament
e, en esta demostracin, nuestros objetos loat, para que nada se caiga el avin. Tam
bin asegrese de ajustar la cmara para que podamos tener una visin clara de la siguie
nte escena:
Donde nuestro tanque y el jugador se desviar en
ahora que tenemos los conceptos bsicos, veremos cmo implementar el depsito, AI carct
er y aspectos de nuestro personaje.
[ 77 ]

Jugador depsito y aspecto


objeto de nuestro objetivo es un simple objeto sphere con la malla render desact
ivado. Tambin hemos creado un punto de luz y hecho un hijo de nuestro objetivo. A
segrese de que la luz est centrado o no ser muy til para nosotros.
Mire el siguiente cdigo en el destino.cs ile:
utilizando UnityEngine; using System.Collections;
public class Target :
transformar targetMarker MonoBehavior { public
void; Actualizacin () { botn int = 0; //Obtener el punto de la posicin de golpe cua
ndo el ratn est siendo // hacer clic.
Si (Input.GetMouseButtonDown(Button) { Ray ray = Cmara.main.ScreenPointToRay(Inpu
t.mousePosition); RaycastHit hitInfo; si (Fsica.Raycast(ray.Origen, Ray.Direccin,
hitInfo) { = hitInfo targetPosition Vector3.El punto; targetMarker.posicin = targ
etPosition; } } } }
adjuntar este script a nuestro objetivo. El script detecta el evento de clic del
mouse y, a continuacin, utilizando la tcnica de raycasting, detecta el mouse haga
clic en el avin en el espacio 3D. Despus de que se actualiza el objeto de destino
a esa posicin en nuestra escena.
[ 78 ]

Reproductor
Reproductor de nuestro depsito depsito depsito simple es el modelo utilizado en el
captulo anterior con un non-cinemtica del cuerpo rgido el componente conectado. El
cuerpo rgido rgano es necesario para generar eventos de activacin cuando hacemos un
a deteccin de colisin con los caracteres AI. La primera cosa que necesitamos hacer
es asignar la etiqueta Reproductor a nuestro depsito.
El depsito est controlada por PlayerTank script, que vamos a crear en un momento.
Este script recupera la posicin de destino en el mapa, y actualiza su punto de de
stino y la direccin correspondiente.
El cdigo en el PlayerTank.cs ile se muestra como sigue:
Usando UnityEngine; using System.Collections;
public class PlayerTank : transformar targetTransform MonoBehavior { pblico; priv
ado de flotacin, rotSpeed movementSpeed;
nulo Inicio () { movementSpeed = 10.0f; rotSpeed = 2.0f; }
void Update () { //Stop una vez que alcanz cerca de la posicin de destino si (Vect
or3.Distancia(transform.posicin, targetTransform.position) &lt; 5.0f);
//retorno de calcular el vector de direccin desde la posicin actual al destino //p
osicin = targetTransform tarPos Vector3.posicin; tarPos.y = transform.position.y;
Vector3 = tarPos dirRot - transform.posicin;
//Crear un Quaternion por esta nueva rotacin vectorial //utilizando el mtodo LookR
otation Quaternion tarRot = Quaternion.LookRotation(dirRot);
[ 79 ]
//mover y rotar con interpolacin transform.ROTACIN= Quaternion.Slerp(transform.rot
acin, tarRot, rotSpeed * Tiempo.deltaTime);
transform.translate(nuevo Vector3(0, 0, * Tiempo movementSpeed.deltaTime)); } }
Propiedades de nuestro objeto del depsito
Este script recupera la posicin del objeto en el mapa, y actualiza su punto de de
stino y la direccin correspondiente. Despus asignamos este script a nuestro depsito
, asegrese de asignar nuestro objeto de destino a la variable targetTransform.
[ 80 ] el

siguiente aspecto, echemos un vistazo al aspecto de la clase.cs. Aspecto es una


clase muy simple con slo una propiedad pblica denominada aspectName. Que todas las
variables que necesitamos en este captulo. Cuando nuestro personaje AI detecta a
lgo, vamos a comprobar con este
aspectName si es el aspecto que la AI ha estado buscando.
El cdigo en el aspecto.cs ile se muestra como sigue:
Usando UnityEngine; using System.Collections;
public class aspecto : aspecto MonoBehavior { public enum { Player, enemigo pblic
o aspectName aspecto }; }
adjuntar este aspecto script a nuestro jugador depsito, y establezca la propiedad
aspectName como enemigo.
Establecer qu aspecto para buscar
caracteres AI
AI nuestro carcter ser recorren la escena en una direccin aleatoria. Tendr dos senti
dos: perspectiva y tacto. La perspectiva sentido comprobar si el enemigo aspecto
est dentro de un rango visible y la distancia. Touch sense detectar si el enemigo
aspecto ha colisionado con el cuadro de hadrones, pronto habr que rodea nuestro c
arcter de AI. Como hemos visto anteriormente, nuestro jugador tanque enemigo tend
r el aspecto. As, estos sentidos se activar cuando detectan el jugador tanque.
El cdigo en el vagar.cs ile pueden mostrarse como sigue:
Usando UnityEngine; using System.Collections;
public class errante : MonoBehavior { private Vector3 tarPos;
[ 81 ]

= 5.0f movementSpeed flotante privado; privado = 2.0f rotSpeed Flotacin Flotacin;


privado, minX, maxX, minZ, maxZ;
// Usar este para inicializacin void Inicio () { minX = -45.0f; maxX = 45,0;
minZ -45.0f = f; maxZ = 45,0 f;
//Obtener posicin errante GetNextPosition(); }
// se llama a Update una vez por fotograma vaco actualizacin () { // comprobar si
estamos cerca de la posicin de destino si (Vector3.Distancia(tarPos, transform.po
sition) &lt;= 5.0f) GetNextPosition(); //Generar nueva posicin aleatoria
// Configurar quaternion para rotacin hacia el destino Quaternion tarRot = Quater
nion.LookRotation(tarPos - transform.posicin);
// actualizacin rotacin y traslacin transform.rotacin = Quaternion.Slerp(transform.r
otacin, Tiempo rotSpeed tarRot, *.deltaTime);
transform.translate(nuevo Vector3(0, 0, * Tiempo movementSpeed.deltaTime)); }
void GetNextPosition() { tarPos = new Vector3(Random.Range(, minX, maxX), 0.5F,
Random.Range(minZ, maxZ)); } }
El vagar script genera una nueva posicin al azar en un rango speciied siempre el
carcter de AI llega a su punto de destino actual. El mtodo Update luego girar nues
tro enemigo, y muvala hacia este nuevo destino. Adjunte este script a nuestro carc
ter de AI para que pueda moverse en la escena.
[ 82 ] El

Sentido
El sentido de clase es la interfaz de nuestro sistema sensorial que los dems sent
idos personalizado puede implementar. Se deines dos mtodos virtuales, inicializar
y UpdateSense, que ser implementado en los sentidos, personalizada y se ejecutan
desde el principio y
mtodos de actualizacin, respectivamente.
El cdigo en el sentido.cs ile pueden mostrarse como sigue:
Usando UnityEngine; using System.Collections;
public class Sense : MonoBehavior { public bool bDebug = true; aspecto pblico.asp
ect aspectName = Aspecto.aspect.enemigo; flotacin pblica detectionRate = 1.0f; pro
tegido de flotacin = 0.0f elapsedTime; virtual protegido void Initialize() { } vo
id UpdateSense virtual protegido() { }
// Usar este para inicializacin void Inicio () { = 0.0f elapsedTime; Initialize()
; }
// se llama a Update una vez por fotograma vaco actualizacin () { UpdateSense(); }
}
propiedades bsicas incluyen su tasa de deteccin para ejecutar la operacin de detecc
in, as como el nombre del aspecto que debera buscar. Este script no estarn conectada
s a cualquiera de nuestros objetos.
Perspectiva
El sentido de perspectiva detectar si un aspecto speciic est dentro de su ield de
vista y distancia visible. Si no ve nada, se tomar la accin speciied.
El cdigo de la perspectiva.cs ile pueden mostrarse como sigue:
Usando UnityEngine; using System.Collections;
[ 83 ] La

perspectiva de clase pblica : sentido { public int FieldOfView = 45; public int V
iewDistance = 100; transformar playerTrans privado; privado Vector3 rayDirection
;
protegido override void Initialize() {
//Buscar jugador posicin
GameObject.FindGameObjectWithTag playerTrans =("Player").transform; }
// se llama a Update una vez por marco protected override void UpdateSense() { e
lapsedTime Tiempo +=.deltaTime;
// detectar el sentido de perspectiva si dentro de la tasa de deteccin si (elapse
dTime detectionRate DetectAspect &gt;=)(); }
//Detectar la perspectiva del campo de visin para el personaje de AI void DetectA
spect() { RaycastHit hit;
//Direccin desde la posicin actual hasta la posicin de jugador rayDirection = playe
rTrans.transform.posicin: posicin;
//controlar el ngulo entre el avance del personaje AI //vector y la direccin Vecto
r entre el jugador y AI si ((vector3.ngulo(rayDirection, transform.forward) &lt;
FieldOfView) { // detectar si el jugador est dentro del campo de visin si (Fsica.Ra
ycast(transform.posicin, rayDirection, golpe, ViewDistance) { aspecto aspecto = hi
t.collider.GetComponent <Aspect>();
si (aspecto != null) { //verificar el aspecto si (aspecto.aspectName == aspectNa
me) { print("enemigo detectado"); } } } } }
[ 84 ]
necesitamos implementar inicializar y UpdateSense mtodos que se llamar desde el in
icio y actualizacin de los mtodos de la clase sentido primario, respectivamente. A
continuacin, en el mtodo, debemos DetectAspect irst verificar el ngulo entre el ju
gador y la direccin actual del AI. Si est en el rango de visin ield, podemos dispar
ar un rayo en la direccin donde el jugador depsito est situado. El rayo de longitud
es el valor de la propiedad visible a distancia. El mtodo devolver Raycast cuando
irst golpea a otro objeto. A continuacin, vamos a comprobar con el componente de
aspecto y nombre de aspecto. De esta forma, incluso si el jugador est en el rang
o visible, el personaje de AI no ser capaz de ver si est oculto detrs de la pared.
El mtodo OnDrawGizmos dibuja lneas basadas en la perspectiva ield de ngulo de visin
y la distancia de visualizacin, de manera que podamos ver la ia del personaje, la
lnea de visin de la ventana del editor durante la reproduccin de la prueba. Adjunt
e este script a nuestro carcter de AI, y asegrese de que el nombre de aspecto est a
justado al enemigo.
Este mtodo puede ilustrarse como sigue:
void OnDrawGizmos() { if (!bDebug || playerTrans == null) volver;
Debug.DrawLine(transform.posicin, playerTrans.La posicin, color
rojo);
Vector3 = frontRayPoint transform.posicin + (transform.forward * ViewDistance);
//visualizacin perspectiva aproximada Vector3 = frontRayPoint leftRayPoint; leftR
ayPoint.x += * FieldOfView 0.5f;
Vector3 = frontRayPoint rightRayPoint; rightRayPoint.x -= * FieldOfView 0.5f;
Debug.DrawLine(transform.posicin, frontRayPoint, Color.green);
Debug.DrawLine(transform.posicin, leftRayPoint, Color.green);
Debug.DrawLine(transform.posicin, rightRayPoint, Color.green); } }
[ 85 ]

toque
otro sentido vamos a aplicar es Touch.cs, que se desencadena cuando el jugador e
s la entidad dentro de una determinada zona, cerca de la entidad AI. Nuestro per
sonaje AI tiene un cuadro de hadrones y su componente es Desencadenante lag est a
ctivado.
Necesitamos implementar OnTriggerEnter evento que ser siempre el componente ired
colisionador de hadrones se choc con otro componente. Desde nuestro depsito tiene
tambin una entidad de hadrones y componentes del cuerpo rgido, eventos de colisin s
er levantada tan pronto como el carcter de la AI colliders y jugador depsito son ch
ocaron.
El cdigo en el Toque.cs ile pueden mostrarse como sigue:
Usando UnityEngine; using System.Collections; public class Touch : sentido { voi
d OnTriggerEnter(Collider) { = otro aspecto aspecto.GetComponent <Aspect>(); si
(aspecto != null) { //verificar el aspecto si (aspecto.aspectName == aspectName)
{ print("enemigo toque detectado"); } } } }
implementamos el evento OnTriggerEnter ired cuando el componente est colisionador
de hadrones choc con otro componente. Desde nuestro depsito tiene tambin una entid
ad de hadrones y los componentes del cuerpo rgido, eventos de colisin ser levantada
tan pronto como el carcter de la AI colliders y el jugador depsito son chocaron.
El collider alrededor nuestro reproductor
[ 86 ]
El grfico anterior muestra el cuadro de hadrones de nuestro enemigo AI que usarem
os para aplicar touch sense. En la siguiente captura de pantalla, podemos ver cmo
nuestro personaje AI est configurado.
Propiedades de nuestro jugador
dentro del mtodo OnTriggerEnter, podemos acceder al componente de aspecto de la o
tra entidad choc y compruebe si el nombre del aspecto es el aspecto de este perso
naje AI est buscando. Y, con fines de demostracin, nosotros simplemente imprima el
enemigo aspecto ha sido detectado por touch sense. Tambin podemos aplicar otros
comportamientos si en proyectos reales; quiz el jugador se darn la vuelta a un ene
migo y empezar a perseguir, atacar, y as sucesivamente.
[ 87 ]

probando
el juego en Unity3D y mover el jugador depsito, cerca de la deambulacin AI carcter
haciendo clic en el suelo. Usted debe ver el enemigo toque mensaje detectado en
el registro de la consola ventana cuando nuestro personaje AI se acerque a nuest
ro jugador tanque.
Nuestro jugador y el tanque en accin
el grfico anterior muestra un agente AI con tacto y perspectiva sentidos buscando
un enemigo aspecto. Coloque el reproductor en la parte delantera del depsito del
personaje de AI, y obtendr el enemigo mensaje detectado. Si usted va a la vista
del editor mientras se ejecuta el juego, usted debera ver los dibujos de depuracin
prestados. Esto es porque el mtodo OnDrawGizmos implementado en el sentido de pe
rspectiva de clase.
Resumen
Este captulo introduce el concepto de la utilizacin de sensores en la aplicacin de
juego AI, y ejecut dos sentidos, perspectiva y touch, por nuestro carcter de AI. E
l sistema sensorial es parte del sistema de toma de decisiones de todo el sistem
a de inteligencia artificial. Podemos utilizar el sistema sensorial en combinacin
con un sistema de comportamiento para ejecutar ciertos comportamientos en ciert
os sentidos. Por ejemplo, podemos usar una FSM para cambiar a perseguir y atacar
a miembros de la patrulla estado una vez hemos detectado que existe un enemigo
dentro de la lnea de visin. Tambin trataremos cmo aplicar el comportamiento de siste
mas de rbol en el Captulo 9, el comportamiento de los rboles. En el prximo captulo, v
eremos cmo aplicar comportamientos de bloqueo en Unity3D, as como de cmo implementa
r Craig Reynold's algoritmo de bloqueo.
[ 88 ]

acudiendo
flocado es la idea de muchos objetos que se mueven juntos como un grupo. Podramos
sentarnos y decirle a cada objeto cmo debe moverse, pero que tendr un montn de tra
bajo. En su lugar, queremos ser capaces de crear un lder de bloqueo a hacer esto
por nosotros. Despus de eso, todo lo que necesitamos es unas cuantas reglas y los
Boidos ser bloquear todas en sus el propios. En este captulo, vamos a aprender cmo
hacer eso y aplicar el comportamiento de bloqueo en Unity3D.
Implementaremos dos variaciones de bloqueo en este captulo. El irst uno se basar e
n una muestra comportamiento de bloqueo encontrado en un proyecto demo llamado I
sla Paraso Tropical. Esta demo viene con Unity en la versin 2.0, pero se ha elimin
ado desde la unidad 3.0. La segunda variacin se basar en Craig Reynold's algoritmo
de bloqueo. Bsicamente, hay tres reglas que se pueden aplicar a cada boid:
Separacin: mantener una distancia con otros vecinos de la cerradura para evitar l
a colisin
La alineacin: Para desplazarse en la misma direccin que el bloqueo, y con la misma
velocidad
Cohesin: Para mantener una distancia mnima con el bloqueo del centro
de la isla de flocado Unidad Demo
en esta seccin, vamos a crear nuestro propio escenario con bloqueos de objetos e
implementar el comportamiento de bloqueo en C#. Existen dos componentes principa
les en este ejemplo: el individuo boid comportamiento y un controlador principal
de mantener y llevar a la multitud.

Nuestra escena jerarqua se muestra en la siguiente captura de pantalla. Como pued


es ver, tenemos varias entidades, UnityFlock boid, bajo un controlador llamado U
nityFlockController.
Boid UnityFlock entidades individuales son objetos, y se va a hacer referencia a
sus padres entidad UnityFlockController para usarlo como un lder. UnityFlockCont
roller actualizar el prximo punto de destino de forma aleatoria una vez que llegue
al punto de destino actual.
Jerarqua de escenas
UnityFlock es un prefab simplemente con un cubo y una malla UnityFlock script. P
odemos utilizar cualquier otra representacin de malla para este lugar prefabricad
o para representar algo ms interesante como las aves.
El comportamiento individual
Boid es un trmino acuado por Craig Reynold que remite a algn pjaro como objeto. Usar
emos este trmino para describir cada objeto individual en nuestra cerradura. Ahor
a vamos a aplicar nuestro comportamiento boid. Puede ind el siguiente script Uni
tyFlock.cs, y este es el comportamiento que controla cada boid en nuestra cerrad
ura.
[ 90 ]

El cdigo en el UnityFlock.cs ile pueden mostrarse como sigue:


Usando UnityEngine; using System.Collections;
public class UnityFlock : MonoBehavior { flotacin pblica minSpeed = 20.0f; flotacin
pblica Velocidadde giro = 20.0f; flotacin pblica randomFreq = 20.0f; flotacin pblica
randomForce = 20.0f;
//alineacin variables flotacin pblica toOriginForce = 50,0f; flotacin pblica toOrigin
Range = 100,0 f;
flotacin pblica gravedad = 2.0f;
//separacin de flotacin pblica avoidanceRadius variables = 50,0f; flotacin pblica avo
idanceForce = 20.0f;
//variables de cohesin flotacin pblica followVelocity = 4.0f; flotacin pblica followR
adius = 40,0f;
//Estas variables controlan el movimiento de la Transformacin privado boid origen
; velocidad; Vector3 privado privado privado normalizedVelocity Vector3; Vector3
randomPush; Vector privado3; privado originPush transformar objetos;[][] otherF
locks UnityFlock privado; transformar transformComponent privado;
declaramos la Los valores de entrada para nuestro algoritmo que puede configurar
se y personalizarse desde el editor. Primero, nos deine el mnimo movimiento, velo
cidad y velocidad de rotacin minSpeed, Velocidadde giro, para nuestro boid. rando
mFreq se utiliza para determinar cuntas veces queremos actualizar la randomPush r
andomForce valor basado en el valor.
Esta fuerza crea un azar aument y disminuy la velocidad y hace que el movimiento d
e bloqueo un aspecto ms realista.
[ 91 ]

toOriginRange speciies cmo repartir queremos bloquear nuestro ser. Tambin utilizam
os
toOriginForce para mantener los Boidos en alcance y mantenga una distancia con e
l origen del bloqueo. Bsicamente, stas son las propiedades para tratar la regla de
alineacin de nuestro algoritmo de bloqueo. El avoidanceForce avoidanceRadius y p
ropiedades se utilizan para mantener una distancia mnima entre los Boidos. Estas
son las propiedades que se aplican la norma de separacin de nuestro bloqueo.
followRadius y followVelocity son usadas para mantener una distancia mnima con el
lder o el origen de la cerradura. Son utilizados para cumplir con la norma de co
hesin del algoritmo de bloqueo.
origen ser el objeto primario para el control de todo el grupo de objetos de bloq
ueo. Nuestro boid necesita saber acerca de los dems boidos en la cerradura. Por l
o tanto, usamos los objetos y
propiedades otherFlocks para almacenar la informacin de los Boidos vecinas.
Este es el mtodo de inicializacin para nuestros boid:
void Inicio () { randomFreq = 1.0f / randomFreq;
//asignar al padre como origen origen = transform.padre;
//Grey transformar transformComponent = transformacin;
//componentes temporales componente[] tempFlocks= null;
//Obtener todos los componentes de la unidad grey del padre //transformacin en el
grupo si (transform.parent) { tempFlocks = transform.parent.GetComponentsInChil
dren <UnityFlock>(); }
// Asignar y almacenar todos los objetos en este grupo flock objetos = nueva tra
nsformacin[tempFlocks.Length]; otherFlocks = new UnityFlock[tempFlocks.Length];
for (int i=0;i <tempFlocks.Length;i++) { objects[i] = tempFlocks[i].transform; o
therFlocks[i] = (UnityFlock)tempFlocks[i]; }
[ 92 ]

//Null Parent as the flock leader will be //UnityFlockController object transfo


rm.parent = null;
//Calculate random push depends on the random frequency //provided StartCorouti
ne(UpdateRandom()); }
We set the parent of the object of our boid as origin, meaning that this will b
e the controller object to follow generally. Then, we grab all the other boids i
n the group and store them in our own variables for later references.
The StartCoroutine method starts the UpdateRandom() method as a coroutine:
IEnumerator UpdateRandom() { while (true) { randomPush = Random.insideUnitSpher
e * randomForce; yield return new WaitForSeconds(randomFreq + Random.Range(-rand
omFreq / 2.0f, randomFreq / 2.0f)); } }
The UpdateRandom() method updates the randomPush value throughout the game with
an interval based on randomFreq. Random.insideUnitSphere returns a Vector3 obje
ct with random x, y, and z values within a sphere with a radius of the randomFor
ce value. Then, we wait for a certain random amount of time before resuming the
while(true) loop to update the randomPush value again.
Now, here's our boid behavior's Update() method that helps our boid entity comp
ly with the three rules of the locking algorithm:
void Update () { //Internal variables float speed = velocity.magnitude; Vector3
avgVelocity = Vector3.zero; Vector3 avgPosition = Vector3.zero; float count = 0
; float f = 0.0f; float d = 0.0f; Vector3 myPosition = transformComponent.positi
on; Vector3 forceV; Vector3 toAvg; Vector3 wantedVel;
[ 93 ]

for (int i = 0;i<objects.Length;i++){ Transform transform= objects[i]; if (tran


sform != transformComponent) { Vector3 otherPosition = transform.position; // Av
erage position to calculate cohesion avgPosition += otherPosition; count++;
//Directional vector from other flock to this flock forceV = myPosition - other
Position;
//Magnitude of that directional vector(Length) d= forceV.magnitude;
//Add push value if the magnitude, the length of the //vector, is less than fol
lowRadius to the leader if (d < followRadius) { //calculate the velocity, the sp
eed of the object, based //on the avoidance distance between flocks if the //cur
rent magnitude is less than the specified //avoidance radius if (d < avoidanceRa
dius) { f = 1.0f - (d / avoidanceRadius); if (d >0) avgVelocity += (forceV / d)
* f * avoidanceForce; }
//slo mantener la distancia con el lder actual f = d / followRadius; UnityFlock ot
herFlocks otherSealgull =[i]; //nos otherSealgull normalizar el vector de veloci
dad para obtener //la direccin del movimiento, entonces debemos fijar una nueva v
elocidad avgVelocity += otherSealgull.normalizedVelocity * f * followVelocity; }
} }
el cdigo anterior implementa la norma de separacin. En primer lugar, debemos compr
obar la distancia entre la actual y la otra boid boidos y actualizar la velocida
d en consecuencia, como se explica en los comentarios.
A continuacin, calculamos la velocidad promedio del bloqueo dividiendo la velocid
ad actual con el nmero de los Boidos en el bloqueo:
si (count &gt; 0) { //Calcular el promedio de velocidad de flock(Alineacin) avgVe
locity /= contar;
[ 94 ]

//calcular el valor central de la grey (Cohesin) = (avgPosition toAvg / count) -


myPosition; } else { toAvg = Vector3.0; }
//Vector direccional al dirigente forceV = origen.posicin - myPosition; D = force
V.magnitud; f = d / toOriginRange;
//calcular la velocidad de la manada al lder si (d &gt; 0) //si ese vaco no est en
el centro de la grey / forceV originPush = (d) * f * toOriginForce;
si (velocidad &lt; minSpeed &amp;&amp; velocidad &gt; 0) { velocidad = / velocid
ad (Velocity) * minSpeed; }
wantedVel = velocidad;
//calcular la velocidad final wantedVel wantedVel -= * Tiempo.deltaTime; wantedV
el randomPush += * Tiempo.deltaTime; wantedVel originPush += * Tiempo.deltaTime;
wantedVel avgVelocity += * Tiempo.deltaTime; wantedVel += toAvg.normaliza * Gra
vedad * Tiempo.deltaTime;
//Velocidad Final para girar el rebao en velocidad = Vector3.RotateToward(velocid
ad, wantedVel, Velocidadde giro * Tiempo.deltaTime, 100.00f);
transformComponent.rotacin = Quaternion.LookRotation(velocidad);
//Mover el rebao, basado en la velocidad calculada transformComponent.translate(v
elocidad * Time.deltaTime, Space.World);
//normalizar la velocidad normalizedVelocity = velocidad.normalizado; } }
[ 95 ]
Finalmente, se suman todos los factores como, randomPush
avgVelocity originPush, y para calcular la velocidad de destino, wantedVel inal.
Tambin actualizamos nuestra velocidad actual a wantedVel con interpolacin lineal
utilizando el Vector3.
Mtodo RotateToward. A continuacin, pasamos nuestro boid basada en la nueva velocid
ad utilizando el mtodo translate().
A continuacin, vamos a crear un cubo de la malla, y agregar esta UnityFlock scrip
t, y hacer de l un lugar prefabricado, como se muestra en la siguiente captura de
pantalla: la
unidad grey prefab
[ 96 ]

controlador
ahora es el momento de crear la clase de controlador. Esta clase actualiza su pr
opia posicin, de modo que el otro individuo objetos boid sabe a dnde ir. Este obje
to al que se hace referencia en el origen variable en el anterior UnityFlock scr
ipt.
El cdigo en el UnityFlockController.cs ile pueden mostrarse como sigue:
Usando UnityEngine; using System.Collections;
public class UnityFlockController : MonoBehavior { public Vector3 offset; public
Vector3 vinculado; flotacin pblica velocidad = 100,0 f;
Vector privado3; privado initialPosition nextMovementPoint Vector3;
// Utilice esta inicializacin void Inicio () { initialPosition = transform.posicin
; CalculateNextMovementPoint(); }
// se llama a Update una vez por fotograma vaco actualizacin () { transform.transl
ate(vector3.forward * Velocidad * Tiempo.deltaTime); transform.rotacin = Quaterni
on.Slerp(transform.rotacin, Quaternion.LookRotation(nextMovementPoint - transform
.posicin), 1.0f * Tiempo.deltaTime);
if (Vector3.Distancia(nextMovementPoint, transform.position) &lt;= 10.0f) Calcul
ateNextMovementPoint(); }
en nuestro mtodo Update(), podemos comprobar si nuestro objeto Controlador est cer
ca del punto de destino. Si es as, actualizamos nuestra variable nextMovementPoin
t nuevamente con el
CalculateNextMovementPoint(), mtodo que acabamos de comentar:
void CalculateNextMovementPoint () { float posX = Random.Range(initialPosition.x
.x, dependiente - initialPosition.x.x) + dependiente; float posY = Random.Range(
initialPosition.y - lmite.y,
[ 97 ]

initialPosition.y + obligado.y); float posZ = Random.Range(initialPosition.z - o


bligado.z, initialPosition.z + enlazado.z);
nextMovementPoint = initialPosition + nuevo Vector3(posX y posY, posZ); } }
La CalculateNextMovementPoint() mtodo inds la prxima posicin destino aleatorio en u
n intervalo entre la posicin actual y el lmite de vectores.
Juntando todo, como se muestra en la captura de pantalla de la jerarqua de la esc
ena anterior, debe tener bloqueos tirados algo realista:
Flocado utilizando la unidad seagull ejemplo
[ 98 ]
implementacin alternativa
aqu es una sencilla aplicacin del algoritmo de bloqueo. En este ejemplo, crearemos
un objeto de cubo y colocar un cuerpo rgido en nuestro boidos. Con unidad de cue
rpo rgido fsica, podemos simplificar la traduccin y el comportamiento de la direccin
de nuestra boid. Para evitar que nuestros boidos de superpuestas entre s, agrega
remos una esfera de hadrones componente fsica.
Tendremos dos componentes de esta aplicacin: individual boid comportamiento y com
portamiento del controlador. El controlador ser el objeto que el resto de los Boi
dos tratar y seguir.
El cdigo en el Rebao.cs ile pueden mostrarse como sigue:
Usando UnityEngine; using System.Collections; using System.Collections.Generic;
public class Grey : { MonoBehavior FlockController controlador interno;
nulo de actualizacin () { if (Contralor) { Vector3 relativePos =() * Tiempo de di
reccin.deltaTime;
si (relativePos != Vector3.cero) rigidbody.velocidad = relativePos;
// aplicar velocidades mnima y mxima de los Boidos = velocidad de flotacin rigidbod
y.velocidad.magnitud; si (velocidad &gt; Controlador.maxVelocity) { rigidbody.ve
locidad = rigidbody.velocidad.normaliza * Controlador.maxVelocity; } else if (ve
locidad &lt; Controlador.minVelocity) { rigidbody.velocidad = rigidbody.velocida
d.normaliza * Controlador.minVelocity; } } }
[ 99 ]

FlockController ser creado en un momento. En nuestro mtodo Update(), podemos calcu


lar la velocidad para nuestros boid utilizando la siguiente direccin(), mtodo y ap
licarlo a su cuerpo rgido velocity. A continuacin, debemos comprobar la velocidad
actual de nuestro cuerpo rgido el componente para comprobar si est en el rango de
nuestro controlador de lmites de velocidad mxima y mnima. Si no, debemos tapar la v
elocidad en el intervalo predeterminado:
privado Vector3 () { direccin centro Vector3 = controlador.transform.localPositio
n flockCenter -; // La cohesin
Vector3 velocidad = controlador.flockVelocity - rigidbody.velocidad; // alineacin
Vector3 siga = controller.target.transform.localPosition localPosition -; // Seg
uir lder de
separacin Vector3 = Vector3.cero; el
mtodo foreach (Grey Grey en controlador.flockList) { if (grey !=) { Vector3 = rel
ativePos transform.localPosition - Bandada.transform.localPosition;
separacin += relativePos / (relativePos.sqrMagnitude); } }
// randomize randomize Vector3 = new Vector3( (Random.value * 2) - 1, (Random.va
lue * 2) - 1, (Random.value * 2) - 1);
randomize.normalize();
return (controlador.centerWeight * centro + controlador.velocityWeight * velocid
ad + controlador.separationWeight * separacin + controlador.followWeight * siga +
controlador.randomizeWeight * randomize); } }
[ 100 ]

El steer() mtodo implementa La separacin, la cohesin, la alineacin y el lder sigue re


glas del algoritmo de bloqueo. Entonces, podemos resumir todos los factores alea
torios junto con un valor de peso. Con este rebao guin junto con cuerpo rgido y esf
era de hadrones componentes, creamos una bandada de prefabricados como se muestr
a en la siguiente captura de pantalla:
Flock
FlockController
FlockController es un simple comportamiento para generar los Boidos en tiempo de
ejecucin y actualizacin del centro de la cerradura as como la velocidad media de l
a cerradura.
El cdigo en el FlockController.cs ile pueden mostrarse como sigue:
Usando UnityEngine; using System.Collections; using System.Collections.Generic;
public class FlockController : MonoBehavior { flotacin pblica minVelocity = 1; //M
in Velocity flotacin pblica maxVelocity = 8; //Mx. velocidad de Flock pblico flockSi
ze int = 20; //Nmero de rebaos en el grupo
//cun lejos los Boidos debern ceirse al centro (la ms //peso stick cerca del centro)
flotacin pblica centerWeight = 1;
flotacin pblica velocityWeight = 1; //comportamiento de alineacin
[ 101 ]

//hasta qu punto cada boid debe separarse de la bandada flotacin pblica separationW
eight = 1;
//Cmo cerrar cada boid debe seguir al lder (la ms //peso hacen la mayor seguimiento
) flotacin pblica followWeight = 1;
//Ruido aleatorio adicional. Flotacin pblica randomizeWeight = 1;
public Grey prefab; Transformacin de pblico objetivo;
//posicin central del rebao en el grupo Vector3 flockCenter interna; Vector3 flock
Velocity interna; //Velocidad media
pblico flockList ArrayList = new ArrayList();
void Inicio () { for (int i = 0; i &lt; flockSize; i++) { Grey Grey = instanciar
(prefab, transform.transform.La posicin, rotacin) como ovejas; ovejas.transform.Pa
rent = transformacin; flock.Controller = este; flockList.Add(grey); } }
declaramos todas las propiedades para aplicar el algoritmo de bloqueo y, a conti
nuacin, comenzar con la generacin de boid objetos basados en el bloqueo de entrada
de tamao. Hemos creado la clase del controlador principal y objeto de transforma
cin, como lo hicimos la ltima vez. A continuacin, aadimos el objeto boid creado en n
uestra funcin de ArrayList. La variable de destino acepta una entidad para ser ut
ilizado como un lder en movimiento. Crearemos una esfera entidad como un blanco mv
il lder de nuestro bloqueo:
void Update () { //calcular el Centro y la velocidad de todo el rebao grupo Vecto
r3 centro = Vector3.cero; Vector3 velocidad = Vector3.cero; el
mtodo foreach (Grey Grey en flockList) { centro += grey.transform.localPosition;
velocidad += grey.rigidbody.velocidad; }
[ 102 ]

flockCenter = centro / flockSize; flockVelocity = velocidad / flockSize; } }


en nuestro mtodo Update(), podemos seguir actualizando la media center y la veloc
idad de la cerradura. Esos son los valores referenciados desde nuestro objeto bo
id, y se usan para ajustar las propiedades de alineacin y de cohesin con el contro
lador.
Controlador de Flock
[ 103 ]
siguiente es nuestro objetivo con la entidad TargetMovement script, que vamos a
crear en un momento. El movimiento script es el mismo que hemos visto en nuestro
anterior Unity3D muestra el movimiento del controlador de secuencia de comandos
:
entidad de destino con TargetMovement script
aqu es cmo nuestra TargetMovement script funciona. Elegimos un punto aleatorio en
las inmediaciones para el destino al que desplazarse. Cuando nos acercamos a ese
momento, elija un nuevo punto. Los boidos seguir entonces el destino.
El cdigo en el TargetMovement.cs ile pueden mostrarse como sigue:
Usando UnityEngine; using System.Collections;
public class TargetMovement : MonoBehavior { //mover alrededor del crculo blanco
con velocidad tangencial Vector3 pblica vinculado; flotacin pblica velocidad = 100,
0 f;
Vector privado3; privado initialPosition Vector3 nextMovementPoint;
nulo Inicio () { initialPosition = transform.posicin; CalculateNextMovementPoint(
); }
[ 104 ]

CalculateNextMovementPoint void () { float posX = Random.Range(initialPosition.x


= enlazado.x.x+enlazado initialPosition.x); float posY = Random.Range(initialPo
sition.y = obligado.y, initialPosition.y+obligado.y); float posZ = Random.Range(
initialPosition.z = enlazado.z, initialPosition.z+enlazado.z);
nextMovementPoint = initialPosition+ nuevo Vector3(posX y posY, posZ); } void Up
date () { transform.translate(vector3.forward * Velocidad * Tiempo.deltaTime); t
ransform.rotacin = Quaternion.Slerp(transform.rotacin, Quaternion.LookRotation(nex
tMovementPoint - transform.posicin), 1.0f * Tiempo.deltaTime);
if (Vector3.Distancia(nextMovementPoint, transform.position) &lt;= 10.0f) Calcul
ateNextMovementPoint(); } }
Despus ponemos todo junto, deberamos Tienen una agradable boidos bloqueo tirados e
n nuestra escena persiguiendo esa meta:
acudiendo con Craig Reynold's algoritmo
[ 105 ]

Resumen
En este captulo, hemos aprendido cmo implementar el comportamiento de bloqueo de d
os maneras. En primer lugar hemos examinado, disecados, y aprendi a aplicar un al
goritmo de bloqueo basado en Unity3D isla tropical del Proyecto Demo. A continua
cin, implementamos con cuerpo rgido para controlar el movimiento y la esfera boid
collider para evitar colisiones con otros boidos. Hemos aplicado nuestro comport
amiento de bloqueo a la mentira de los objetos, pero se le puede aplicar las tcni
cas en esos ejemplos para aplicar otro personaje comportamientos como ish shoali
ng, enjambre de insectos, o tierras de pastoreo de los animales. Slo tendr que imp
lementar diferentes comportamientos de movimiento leader como limitar el movimie
nto a lo largo del eje y para caracteres que no se pueden mover hacia arriba y h
acia abajo. Para un juego 2D, nos acaba de congelar la posicin y. Para 2D el movi
miento a lo largo de terrenos desparejos, tendramos que modificar nuestro script
para no poner todas las fuerzas en la direccin Y.
En el prximo captulo, vamos a ir ms all de movimiento aleatorio y echar un vistazo e
n la ruta siguiente. Tambin estaremos yendo sobre cmo evitar los obstculos que se e
ncuentran en su camino.
[ 106 ]
Ruta siguientes comportamientos de direccin y
esto ser un simple y breve captulo, y vamos a implementar dos Unity3D escenas.
En el irst ejemplo, vamos a configurar una escena con una ruta y escribir algn sc
ript para hacer una entidad siga este camino. En el segundo ejemplo, vamos a con
figurar una escena con un par de obstculos y programa una entidad para alcanzar u
na meta evitando los obstculos. Superacin de obstculos es un simple comportamiento
de la AI entidades para llegar a un punto de destino. Es importante sealar que el
comportamiento speciic implementado en este captulo est destinado a uso de compor
tamientos, tales como simulacin de multitudes, donde el objetivo principal de cad
a entidad agente es simplemente para evitar los otros agentes y llegar a la meta
. No hay ninguna consideracin sobre cul sera el ms eficient y la ruta de acceso ms co
rta. Vamos a aprender sobre el algoritmo A* pathinding en el siguiente captulo.

Siguiendo un sendero
rutas son generalmente creadas por conexin de waypoints juntos. As, vamos a config
urar una ruta simple, como se muestra en el siguiente grfico y, a continuacin, hac
er nuestra entidad cubo siga por el camino sin contratiempos. Ahora, hay muchas
maneras de construir ese camino. La vamos a implementar aqu posiblemente podra ser
uno de los ms sencillos. Escribiremos un script llamado Ruta.cs y almacenar todo
s los waypoint posiciones en una matriz de Vector3. Entonces, desde el editor, v
amos a introducir esas posiciones manualmente. Es un poco tedioso proceso ahora.
Una opcin es utilizar la posicin de un objeto juegos vaca como puntos de referenci
a. O, si lo desea, puede crear su propio editor plugins para automatizar este ti
po de tareas, pero eso est fuera del alcance de este libro. Por ahora, debe ser i
ne waypoint simplemente introduzca la informacin manualmente, ya que el nmero de w
aypoints que estamos creando aqu no son tan importantes.
Ruta de objeto, en
primer lugar, creamos un juego vaco de entidad y agregar nuestro camino component
e script como se muestra en la siguiente captura de pantalla:
[ 108 ]

Aqu es cmo la Jerarqua est organizada


, entonces nosotros rellenar nuestro punto una variable con todos los puntos que
queremos ser incluidos en nuestro camino:
Propiedades de nuestro camino script
[ 109 ]

La lista anterior muestra los puntos de referencia necesarios para crear la ruta
de acceso que se describi anteriormente. Las otras dos propiedades son el modo d
e depuracin y Radius. Si la propiedad Modo de depuracin est activada, el camino for
mado por las posiciones introducido ser dibujado como gizmos en la ventana del ed
itor. La propiedad radius es un valor de intervalo para la ruta siguiente entida
des a utilizar de modo que se puede saber cuando se ha alcanzado un determinado
punto de referencia si estn en esta gama de radio. Ya que para llegar a una posic
in exacta puede ser bastante difcil, esta gama valor radio proporciona una forma e
ficaz para que la ruta de acceso siguientes agentes para navegar a travs de la ru
ta.
Script de ruta
as que echemos un vistazo a la ruta de la secuencia de comandos. Ser responsable d
e la gestin de la ruta para nuestros objetos. Mira el siguiente cdigo en el camino
.cs ile:
utilizando UnityEngine; using System.Collections;
public class Path : MonoBehavior { public bool bDebug = true; flotacin pblica Radi
o = 2.0f; public Vector3[] pointA;
Longitud de flotacin pblica { get { return pointA.Length; } }
pblico GetPoint Vector3(int index) { return pointA[index]; }
void OnDrawGizmos() { if (!bDebug) volver;
para (int i = 0; i &lt;pointA.Length; i++) { if (i + 1 <pointA.Length) { Debug.D
rawLine(pointA[i], pointA[i + 1], Color.red); } } } }
[ 110 ]

As you can see, that is a very simple script. It has a Length property that ret
urns the length and size of the waypoint array if requested. The GetPoint method
returns the
Vector3 position of a particular waypoint at a speciied index in the array. The
n, we have the OnDrawGizmos method that is called by Unity3D frame to draw compo
nents in the editor environment. The drawing here won't be rendered in the game
view unless gizmos, located in the top right corner of the game view, is turned
on.
Path follower
Next we have our vehicle entity, which is just a simple cube object in this exa
mple.
We can replace the cube later with whatever 3D models we want. After we create
the script, we add the VehicleFollowing script component as shown in the followi
ng screenshot:
Properties of our Vehicle Following script
The script takes a couple of parameters. First is the reference to the path obj
ect it needs to follow. Then, the Speed and Mass properties, which are needed to
calculate its acceleration properly. Is Looping is a lag that makes this entity
follow the path continuously if it's checked. Let's take a look at the followin
g code in the
VehicleFollowing.cs ile:
using UnityEngine; using System.Collections;
public class VehicleFollowing : MonoBehaviour { public Path path; public float
speed = 20.0f; public float mass = 5.0f; public bool isLooping = true;
//Actual speed of the vehicle private float curSpeed;
[ 111 ]

private int curPathIndex; private float pathLength; private Vector3 targetPoint


;
Vector3 velocity;
First, we initialize the properties and set up the direction of our velocity ve
ctor with the entity's forward vector in the Start method, as shown in the follo
wing code:
void Start () { pathLength = path.Length; curPathIndex = 0;
//get the current velocity of the vehicle velocity = transform.forward; }
There are only two methods that are important in this script, the Update and St
eer methods. Let's take a look at the following code:
void Update () { //Unify the speed curSpeed = speed * Time.deltaTime;
targetPoint = path.GetPoint(curPathIndex);
//If reach the radius within the path then move to next //point in the path if
(Vector3.Distance(transform.position, targetPoint) < path.Radius) { //Don't move
the vehicle if path is finished if (curPathIndex < pathLength - 1) curPathIndex
++; else if (isLooping) curPathIndex = 0; else return; }
//Move the vehicle until the end point is reached in //the path if (curPathInde
x >= longitud de trayectoria de retorno );
//calcular la siguiente velocidad hacia la ruta si (curPathIndex &gt;= longitud
de trayectoria-1&amp;&amp; !isLooping) Velocidad +=(direccin targetPoint, true);
else velocidad +=(targetPoint Steer);
[ 112 ]

//mover el vehculo segn la velocidad transform.posicin += velocidad; //Girar el vehc


ulo a la velocidad deseada transform.rotacin = Quaternion.LookRotation(velocidad)
; }
en el mtodo Update, debemos comprobar si nuestra entidad ha llegado a un punto de
referencia determinado por el clculo de la distancia entre su posicin actual y la
ruta del radio de alcance. Si se encuentra en el rango, acabamos de aumentar el
ndice para buscar a partir de la matriz de puntos de referencia. Si es el ltimo p
unto de referencia, comprobamos si el lag isLooping est establecido. Si se establ
ece, entonces debemos fijar el objetivo para el punto de referencia inicial. De
lo contrario, acabamos de parar en ese punto. Sin embargo, si quisiramos, podramos
hacer as nuestro objeto volte y volvi la manera en que entr. En la prxima parte, vam
os a calcular la aceleracin desde el
mtodo de direccin. Entonces, cambiamos nuestra entidad y actualizar la posicin segn
la velocidad y la direccin de la velocidad:
//algoritmo de direccin para dirigir el vector hacia el pblico meta Vector3 dirigi
r(vector3 objetivo, bool bFinalPoint = false) { //calcular el vector direccional
desde el actual //posicin hacia el punto de destino Vector3 desiredVelocity = (t
arget -transform.posicin); float dist = desiredVelocity.magnitud;
//Normalizar la velocidad deseada desiredVelocity.normalize();
//calcular la velocidad segn la velocidad si (bFinalPoint&amp;&amp;dist&lt;10.0f)
= (curSpeed desiredVelocity * * (dist / 10.0f); else desiredVelocity *= curSpeed
;
//calcular la fuerza Vector Vector3 = desiredVelocity steeringForce - velocidad;
Vector3 aceleracin = steeringForce / Mass;
volver la aceleracin; } }
[ 113 ]

El mtodo de direccin toma el parmetro; objetivo Vector3 para situar, si esta es la


Inal waypoint de la ruta. La primera cosa que debemos hacer es calcular la dista
ncia restante desde la posicin actual hasta la posicin de destino. La posicin de de
stino menos vectorial de la posicin actual del vector Un vector da hacia la posic
in de destino vector.
La magnitud de este vector es la distancia restante. Luego nos normalizar este v
ector solo para preservar la propiedad direction. Ahora bien, si este es el ltimo
punto de referencia, y la distancia es de menos de 10 de un nmero hemos decidido
utilizar, aminorar la velocidad gradualmente segn la distancia restante hasta nu
estro punto hasta la velocidad originalmente se convierte en cero. De lo contrar
io, acabamos de actualizar el destino speciied velocity con el valor de velocida
d. Restando el vector de velocidad actual de esta meta vector de velocidad, pode
mos calcular el vector de direccin nueva. A continuacin, dividiendo este vector co
n el valor de masa de nuestra entidad, obtenemos la aceleracin.
Si ejecuta la escena, usted debe ver a su objeto de cubo siguiendo el camino. Ta
mbin puede ver el camino que se dibuja en la vista del editor. Jugar con la veloc
idad y el valor de masa del seguidor y valores de radio de la ruta y ver cmo afec
tan el comportamiento global del sistema.
Evita los obstculos
en esta seccin, vamos a configurar una escena tal como se muestra en la siguiente
captura de pantalla, y hacer que nuestra entidad AI evitar los obstculos al inte
ntar llegar al punto de destino. El algoritmo presentado aqu utilizando el mtodo d
e raycasting es muy simple, por lo que slo puede evitar los obstculos que bloquean
el camino delante de ti. La siguiente captura de pantalla nos mostrar qu nuestra
escena ser similar a la siguiente:
configurar una escena de ejemplo
[ 114 ]

para crear este, hacemos unas pocas entidades de cubo y agruparlos en un objeto
llamado juegos vaca obstculos. Tambin podemos crear otro objeto denominado Agente d
e cubo y darle nuestro script de evitacin de obstculos. A continuacin, creamos un o
bjeto plano de tierra para ayudar a encontrar una posicin de destino.
Aqu es cmo est organizada la jerarqua
vale la pena sealar que este agente no es un objeto pathinder. Como tal, si hacem
os demasiadas paredes, nuestro agente podra tener un tiempo difcil encontrar el de
stino. Pruebe unas cuantas configuraciones de pared y ver cmo nuestro agente real
iza.
[ 115 ]

aadiendo una capa personalizada


Ahora aadiremos una capa personalizada a nuestro objeto. Para agregar una nueva c
apa, nos vaya a Editar | Configuracin del proyecto | Etiquetas. Asigne el nombre
de usuario de obstculos a la Capa 8. Ahora, regresemos a nuestra entidad de cubo
y establezca su propiedad de capa a los obstculos.
Crear una nueva capa
Esta es nuestra nueva capa, que se aade a la Unity3D. Ms tarde, cuando hacemos el
ray casting para detectar obstculos, vamos a controlar nicamente para aquellas ent
idades que utilizan esta capa en particular. De esta manera, podemos hacer caso
omiso de algunos objetos que no son obstculos que estn siendo afectadas por un ray
o, como arbustos o vegetacin.
Asignacin de nuestra nueva capa
para grandes proyectos, nuestros objetos del juego, probablemente ya tiene una c
apa asignados a ellos.
Como tal, en lugar de cambiar la capa del objeto de obstculos, tendramos que hacer
una lista con los mapas de bits de capas para nuestra entidad de cubo para util
izar a la hora de detectar obstculos. Hablaremos ms acerca de mapas de bits en la
siguiente seccin.
Las capas son ms comnmente utilizados por las cmaras para representar una parte de
la escena y las luces para iluminar slo algunas partes de la escena. Pero, tambin
pueden ser utilizados por ray casting ignorar selectivamente colliders o crear l
as colisiones. Usted puede aprender ms sobre esto en Http://docs.unity3d.
com/Documentation/Componentes/Capas.html.
[ 116 ]
eludir obstculos
ahora es el momento de hacer que el script que ayudar a nuestra entidad cubo evit
ar esas paredes.
Propiedades de nuestro vehculo evitar script
Como de costumbre, nosotros irst inicializar nuestra entidad script con las prop
iedades predeterminadas y dibujar una GUI en nuestro texto OnGUI mtodo. Veamos el
siguiente cdigo en la
ILE VehicleAvoidance.cs:
utilizando UnityEngine; using System.Collections;
public class VehicleAvoidance : MonoBehavior { flotacin pblica velocidad = 20.0f;
flotacin pblica misa = 5.0f; flotacin pblica fuerza = 50,0f; flotacin pblica minimumDi
stToAvoid = 20.0f;
//la velocidad real del vehculo privado; privado curSpeed flotacin targetPoint Vec
tor3;
// Utilice esta inicializacin void Inicio () { = 5.0f masiva; targetPoint = Vecto
r3.cero; }
void OnGUI() { GUILayout.Etiqueta("Haga clic en cualquier lugar para mover el ve
hculo."); }
luego en nuestro mtodo Update, actualizamos la entidad agente la posicin y rotacin
basado en el vector devuelto por el mtodo AvoidObstacles:
//Update se llama una vez en cada fotograma vaco de actualizacin () { //vehculo se
mueven mediante ratn RaycastHit golpeado;
[ 117 ]

var ray = Cmara.main.ScreenPointToRay (Input.mousePosition);


if (Input.GetMouseButtonDown(0) &amp;&amp; fsica.Raycast(ray, golpe, 100,0 f)) { t
argetPoint = hit.El punto; }
//vector direccional a la posicin de destino Vector3 dir = (targetPoint - transfo
rm.posicin); dir.normalizar();
//Aplicar eludir obstculos AvoidObstacles(ref dir);
//...
}
La primera cosa que hacemos en nuestro mtodo Update es recuperar el mouse haga cl
ic en posicin, de modo que podemos mover nuestra entidad AI. Hacemos esto para di
sparar un rayo de la cmara en la direccin en la que est buscando. A continuacin, tom
amos el punto donde el rayo golpe el suelo plano que nuestra posicin de destino. U
na vez que obtenemos el vector de posicin de destino, podemos calcular el vector
de direccin restando la posicin actual del vector de vectores de la posicin de dest
ino. A continuacin, llamamos al mtodo AvoidObstacles y pase este vector de direccin
:
//calcular el nuevo vector direccional para evitar //el obstculo public void Avoi
dObstacles(ref Vector3 dir) { RaycastHit hit;
//slo detectan la capa 8 (Obstculos) int layerMask = 1&lt;&lt;8;
//verificar que el vehculo golpee con los obstculos dentro de //es la distancia mni
ma para evitar si (Fsica.Raycast(transform.posicin, transform.adelante, golpe, mini
mumDistToAvoid, layerMask)) { //Obtener el normal del golpe para calcular //nuev
o Vector3 = hit hitNormal.normal; hitNormal.y = 0.0f; //No queremos mover Y-Espa
cio
[ 118 ]
//Obtener el nuevo vector direccional aadiendo fuerza a //avance actual del vehcul
o vector dir = transform.avance + hitNormal * vigor; } } }
El mtodo AvoidObstacles tambin es bastante simple. El nico truco a tener en cuenta
aqu es que raycasting interacta de manera selectiva con los obstculos que nos speci
ied de capa en capa 8 usuario en nuestro Unity3D Tag Manager. El mtodo Raycast ac
epta un parmetro de la mscara de capa para determinar qu capas de ignorar y que par
a considerar durante el raycasting. Ahora, si miramos cmo muchas capas que se pue
den especificar en Tag Manager, podr ind un total de 32 capas. Por lo tanto, Unit
y3D utiliza un nmero entero de 32 bits para representar este parmetro de la mscara
de capa. Por ejemplo, la siguiente representara un cero en 32 bits:
0000 0000 0000 0000 0000 0000 0000 0000
Por defecto Unity3D utiliza el irst ocho capas como construida en capas. Por lo
tanto, cuando usted raycast sin utilizar un parmetro de la mscara de capa, tendr ra
ycast contra todos aquellos ocho capas, que puede ser representada como la sigui
ente en una mscara de bits:
0000 0000 0000 0000 0000 0000 1111 1111
nuestra capa de obstculos se fij en la capa 8 (ndice 9), y slo queremos raycast cont
ra esta capa. Por lo tanto, nos gustara establecer nuestra mscara de bits de la si
guiente manera:
0000 0000 0000 0000 0000 0001 0000 0000
La manera ms sencilla de configurar esta mscara de bits es utilizando los operador
es de desplazamiento de bits. Slo tenemos que colocar el 'on' o el bit 1, en la n
ovena ndice, lo cual significa que podemos mover ese bit 8 lugares hacia la izqui
erda. Por lo tanto, utilizamos el operador de desplazamiento a la izquierda para
mover el bit 8 lugares hacia la izquierda, como se muestra en el siguiente cdigo
:
int layerMask = 1&lt;&lt;8;
Si queremos usar varias mscaras de capa, es decir la capa 8 y Capa 9, una forma fc
il sera utilizar el operador OR en modo bit como esta:
int layerMask = (1&lt;&lt;8) | (1&lt;&lt;9);
tambin puede ind una buena discusin sobre el uso layermasks en Unity3D online. La
pregunta y la respuesta se puede encontrar en el sitio Http://answers.unity3d.co
m/ preguntas/8715/cmo-do-i-uso-layermasks.html.
[ 119 ]

Una vez que tengamos la mscara de capa, llamamos al mtodo Raycast fsica.a partir de
la actual posicin de la entidad y en la direccin de avance. Para la longitud del
rayo, utilizamos nuestra minimumDistToAvoid variable, de forma que slo vamos a ev
itar los obstculos que estn siendo afectadas por el rayo dentro de esta distancia.
A continuacin, tomamos el vector normal del hit ray, multiplicar la fuerza con el
vector, y agregarla a la actual direccin de nuestra entidad para obtener la nuev
a direccin resultante de vectores, que nos devuelva este mtodo.
Cmo nuestra entidad cubo evita una pared
luego en nuestro mtodo Update, utilizamos esta nueva direccin despus, evitando obstc
ulos para rotar la entidad AI y actualizar la posicin segn el valor de la velocida
d de
actualizacin. void () {
//...
//No mover el vehculo cuando el punto de destino //es alcanzado si (Vector3.Dista
ncia(targetPoint, transform.position) &lt; 3.0f) volver;
//asignar la velocidad con tiempo delta curSpeed = velocidad * Tiempo.deltaTime;
//gire el vehculo hasta su destino //vector direccional
[ 120 ]
var rot = Quaternion.LookRotation(dir); transform.rotacin = Quaternion.Slerp (tra
nsform.la rotacin, la putrefaccin, 5.0f * Tiempo.deltaTime);
//mover el vehculo hacia transform.posicin += transform.adelante * curSpeed; }
Resumen
En este captulo, hemos creado dos escenas y estudi cmo construir camino siguiendo l
os agentes junto con comportamientos de evitacin de obstculos. Hemos aprendido sob
re el Unity3D capa caracterstica y cmo raycast selectivamente contra una capa dete
rminada. Aunque las muestras eran simples, podemos aplicar esas tcnicas simples e
n diversos escenarios.
Por ejemplo, podemos definir una ruta a lo largo de una carretera, y mediante el
uso de algunos modelos de vehculos combinados con comportamiento de evitacin de o
bstculos, podemos configurar fcilmente una decente trafic simulacin. O simplemente
puedes reemplazarlos con bpedo personajes y construir multitud de simulacin. Tambin
puede combinarlos con algunos Estados inite aadir algunos ms comportamientos para
hacerlos ms inteligentes. Este simple comportamiento de evitacin de obstculos que
se implement en este captulo no se considera el mejor camino para llegar a la posi
cin de destino. En lugar de ello, simplemente va directamente a ese destino, y slo
si un obstculo es visto dentro de una determinada distancia, intenta evitar. Se s
upone que se utiliza entre mover o de objetos dinmicos y obstculos.
En el siguiente captulo, estudiaremos cmo implementar un algoritmo llamado pathind
ing A* para determinar la ruta ptima antes de mover, evitando obstculos estticos.
[ 121 ]

* Pathinding
en este captulo, vamos a aplicar el algoritmo A* en Unity3D entorno utilizando C#
.
El algoritmo A* pathinding es ampliamente utilizado en los juegos y aplicaciones
interactivas, aunque existen otros algoritmos, como el algoritmo de Dijkstra, d
ebido a su sencillez y eficacia. Hemos cubierto este algoritmo briely anteriorme
nte en el Captulo 1, Introduccin a la AI. Pero vamos a revisar el algoritmo de nue
vo desde la perspectiva de la implementacin.
Algoritmo A* volver
vamos a revisar el algoritmo A* de nuevo antes de proceder a la aplicacin en la s
iguiente seccin. En primer lugar, necesitaremos para representar el mapa en una e
structura de datos traversable.
Aunque muchas de las estructuras son posibles, para este ejemplo, usaremos un 2D
grid array.
Implementaremos la clase GridManager posteriormente para manejar esta informacin
de mapas. Nuestra
clase GridManager mantendr una lista de los objetos de nodo que son bsicamente ttul
os en una cuadrcula 2D. As que tenemos que aplicar esa clase de nodo para manejar
cosas tales como tipo de nodo; si se trata de un nodo traversable o un obstculo,
el costo de su pase y el coste para alcanzar la meta el nodo, y as sucesivamente.
Tendremos dos variables para almacenar los nodos que han sido procesados y los n
odos que tenemos en proceso. Vamos a llamarlos lista cerrada y abrir la lista, r
espectivamente. Vamos a aplicar ese tipo de lista de la clase PriorityQueue. Y,
a continuacin, originalmente, el siguiente algoritmo A* ser implementado en la cla
se AStar. Echemos un vistazo:
1. En primer lugar, comenzaremos con el nodo inicial y ponerlo en la lista abier
ta.
2. Mientras la lista abierta tiene algunos nodos, vamos a realizar el siguiente
proceso.
3. Escoja el irst nodo de la lista abierta y mantenerlo como el nodo actual.
(suponiendo que se ha ordenado la lista abierta y el irst nodo tiene el valor de
coste mnimo, que sern mencionados al final del cdigo.)

4. Obtenga los nodos vecinos de este nodo actual, que no son tipos de obstculo, c
omo una pared o un can que no se pueda pasar.
5. Para cada nodo vecino, comprobar si este nodo vecino ya est en la lista cerrad
a. Si no vamos a calcular el coste total (F) para este nodo vecino utilizando la
siguiente frmula:
F = G + H
en la frmula anterior, G es el coste total del nodo anterior a este nodo y H es e
l costo total de este nodo a la inal del nodo de destino.
6. Almacenar los datos de los costes en que el objeto nodo vecino. Asimismo, alm
acenar el nodo actual como el nodo primario. Ms tarde utilizaremos este nodo padr
e datos para rastrear la ruta real.
7. Poner este nodo vecino en la lista abierta. Ordenar la lista abierta en orden
ascendente, ordenada por el coste total para llegar al nodo de destino.
8. Si no hay ms nodos vecinos al proceso, poner el nodo actual en la lista cerrad
a y quitarlo de la lista abierta.
9. Volver al paso 2.
Una vez que haya completado este proceso tu nodo actual debe estar en la posicin
de los nodos de objetivo, pero slo si existe una ruta libre de obstculos para alca
nzar la meta del nodo del nodo de inicio. Si no est en el nodo objetivo, entonces
no hay ninguna ruta disponible para el nodo de destino desde la posicin del nodo
actual. Si hay un camino vlido todo lo que tenemos que hacer ahora es rastrear d
esde actual nodo padre, hasta llegar al nodo Iniciar de nuevo. Que nos d una list
a de rutas de todos los nodos que elegimos durante nuestro proceso pathinding or
den desde el nodo de destino para el nodo de inicio. Luego nos acaba de invertir
esta lista de ruta, pues queremos saber la ruta desde el nodo inicial hasta el n
odo objetivo.
Esta es una descripcin general del algoritmo que vamos a implementar en Unity3D u
tilizando C#. As que vamos a empezar.
Aplicacin
implementaremos las clases preliminares que se mencionaron antes, tales como el
nodo, la clase y la clase GridManager PriorityQueue clase. A continuacin, usaremo
s en nuestros principales AStar clase.
[ 124 ]

El nodo nodo class manejar cada mosaico objeto en nuestra rejilla 2D que represen
tan los mapas mostrados en el nodo.cs ile:
utilizando UnityEngine; using System.Collections; using System;
public class Nodo : IComparable { flotacin pblica nodeTotalCost; flotacin pblica est
imatedCost; public bool bObstacle; public nodo padre; Vector3 posicin pblica;
public node() { this.estimatedCost = 0.0f; esto.nodeTotalCost = 1.0f; esto.bObst
acle = false; this.Parent = null; }
Public Node(vector3 pos) { this.estimatedCost = 0.0f; esto.nodeTotalCost = 1.0f;
esto.bObstacle = false; this.Parent = NULL; esto.posicin = pos; }
public void MarkAsObstacle() { this.bObstacle = true; }
La clase de nodo tiene propiedades, como los valores de costo (G y H), LAG a mar
car si es un obstculo, sus posiciones y sus padres Nodo. La nodeTotalCost es G, q
ue es el valor de coste de movimiento desde el nodo inicial a este nodo hasta ah
ora y la estimatedCost es H, que es el coste total estimado de este nodo hasta e
l nodo objetivo. Tambin tenemos dos sencillos mtodos constructor y un mtodo de ajus
tador para establecer si este nodo es un obstculo. A continuacin, aplicamos el mtod
o CompareTo como se muestra en el cdigo siguiente:
public int CompareTo(object obj) { = Node (Nodo)obj; //valor negativo significa
que se presenta ante este objeto en la clase //orden.
Si (this.estimatedCost &lt; node.estimatedCost)
[ 125 ]

devuelven -1; //valor positivo significa que el objeto viene despus de esto en la
clase //orden.
Si (this.estimatedCost &gt; nodo.estimatedCost) return 1; return 0; } }
Este mtodo es importante. Nodo de nuestra clase hereda de IComparable porque quer
emos reemplazar este mtodo CompareTo. Si usted puede recordar lo que hemos debati
do en el algoritmo anterior seccin, te dars cuenta de que tenemos que ordenar nues
tra lista de matrices de nodo basado en el costo total estimado. El tipo ArrayLi
st tiene un mtodo llamado ordenar. Ordenar bsicamente busca este mtodo CompareTo, i
mplementado dentro del objeto (en este caso nuestro nodo objetos) de la lista. A
s, podemos aplicar este mtodo para ordenar los objetos basados en el nodo estimate
dCost nuestro valor. Usted puede aprender ms sobre esta caracterstica de .NET Fram
ework en el siguiente recurso.
El mtodo IComparable.CompareTo puede encontrarse en Http://msdn.microsoft.com/en-
us/library/ system.icomparable.compareto.aspx.
Un PriorityQueue PriorityQueue es una corta y simple clase para realizar la mani
pulacin de los nodos,
ArrayList ms fcil, como se muestra en la siguiente clase PriorityQueue.cs:
utilizando UnityEngine; using System.Collections;
public class PriorityQueue { private ArrayList nodos = new ArrayList();
public int length { get { return this.nodes.Count; } }
public bool Contains(object node) { return this.nodes.Contains(nodo); }
Primer nodo pblico() { if (this.nodes.Count &gt; 0) { return (nodo)Este.nodos[0];
}
[ 126 ]

devolver null; }
public void Push(node) { this.nodes.Add(nodo); este.nodes.Sort(); }
public void Remove(node) { this.nodes.Remove(nodo); //asegurar la lista se orden
a este.nodes.Sort(); } }
El listado de cdigo anterior debe ser fcil de entender. Una cosa para notar es que
despus de aadir o quitar el nodo desde los nodos' ArrayList, llamamos al mtodo Sor
t. Esto exigir el nodo del objeto mtodo CompareTo, y ordenar los nodos estimatedCo
st en consecuencia por el valor.
Una clase GridManager GridManager maneja todas las propiedades de la cuadrcula re
presenta el mapa.
Mantendremos una instancia singleton de la clase GridManager, necesitamos slo un
objeto para representar el mapa, como se muestra en la siguiente GridManager.cs
ile:
utilizando UnityEngine; using System.Collections;
public class GridManager : MonoBehavior { private static GridManager s_instance
= null;
public static GridManager ejemplo { get { if (s_instance == null) { s_instance =
FindObjectOfType(typeof(GridManager) como GridManager; Si (s_instance == null)
Debug.log("No se pudo localizar un GridManager " + "objeto. \n debe tener exacta
mente " + "uno GridManager en la escena."); } devolver S_Instance; } }
[ 127 ]

buscamos el objeto GridManager en nuestra escena y si lo encuentra, lo mantenemo


s en nuestra
s_Instance variable esttica.
public int numOfRows; public int numOfColumns; flotacin pblica gridCellSize; publi
c bool showGrid = true; public bool showObstacleBlocks = true;
privado origen Vector3 = new Vector3(); privada; obstacleList GameObject[][,] no
do pblico nodos { GET; set; } pblico origen Vector3 { get { return origen; } }
Ahora, declarar todas las variables; necesitaremos para representar nuestro mapa
, tales como el nmero de filas y columnas, el tamao de cada cuadrcula de mosaico, y
algunas variables de tipo boolean para visualizar la cuadrcula y Obstculos, as com
o almacenar todos los nodos de la cuadrcula como se muestra en el siguiente cdigo:
void despierto() { obstacleList = GameObject.FindGameObjectsWithTag("obstculo");
CalculateObstacles(); } // Buscar todos los obstculos en el mapa void CalculateOb
stacles() { nodos = nuevo nodo[numOfColumns, numOfRows]; int index=0; for (int i
= 0; i &lt; numOfColumns; i++) { for (int j = 0; j &lt; numOfRows; J++) { Vecto
r3 = GetGridCellCenter cellPos(index); Node = Nuevo Nodo(cellPos); nodos[i, j] =
nodo; index++; } } Si (obstacleList != null &amp;&amp; obstacleList.length &gt;
0) { //para cada obstculo encontrado en el mapa, grabarlo en nuestra lista (dato
s GameObject foreach en obstacleList) { int = GetGridIndex indexCell(data.transf
orm.posicin); int col = GetColumn(indexCell); int fila =(indexCell GetRow); nodos
[fila, col].MarkAsObstacle(); } } }
[ 128 ]

Buscamos todos los objetos del juego con una etiqueta de obstculo y ponerlos en n
uestra propiedad obstacleList. A continuacin, establecemos nuestro nodos' 2D
CalculateObstacles array en el mtodo. En primer lugar, acabamos de crear el nodo
normal de objetos con propiedades predeterminadas. Justo despus de que examinemos
nuestro obstacleList. Convertir su posicin en la fila, la columna de datos y act
ualizar los nodos en ese ndice para ser obstculos.
La GridManager tiene un par de mtodos auxiliares para recorrer la cuadrcula y obte
ner los datos de las celdas de la cuadrcula. Los siguientes son algunos de ellos
con una breve descripcin de lo que hacen. La aplicacin es simple, as que no entrare
mos en los detalles.
El mtodo GetGridCellCenter devuelve la posicin de la celda de la cuadrcula de coord
enadas del mundo desde el ndice de celda, como se muestra en el siguiente cdigo:
Public Vector3 GetGridCellCenter(int index) { Vector3 = GetGridCellPosition cell
Position(index); cellPosition.x += (gridCellSize / 2.0f); cellPosition.z += (gri
dCellSize / cellPosition 2.0f); return; }
pblico GetGridCellPosition Vector3(int index) { int fila = GetRow(index); int col
= GetColumn(index); float xPosInGrid = col * gridCellSize; float zPosInGrid = f
ila * gridCellSize; retorno origen + nuevo Vector3(xPosInGrid, 0.0F, zPosInGrid
GetGridIndex); } El mtodo devuelve el ndice de la celda de cuadrcula en la cuadrcula
de la posicin dada:
public int GetGridIndex(vector3 pos) { if (!IsInBounds(pos) { return -1; } pos -
= origen; int col = (int)(pos.x / gridCellSize); int fila = (int)(pos.z / gridCe
llSize); return (fila * numOfColumns + col); }
public bool IsInBounds(vector3 pos) { float ancho = numOfColumns * gridCellSize;
altura de flotacin =* numOfRows gridCellSize; retorno (pos.x &gt;= origen.x &amp
;&amp; pos.x &lt;= origen.x + Ancho &amp;&amp; pos.x &lt;= origen.z + altura &am
p;&amp; pos.z &gt;= origen.z); }
[ 129 ]

La GetRow y GetColumn mtodos devuelven la fila y columna de la celda de la cuadrcu


la de datos del ndice dado:
public int GetRow(int index) { int = ndice de fila / numOfColumns; volver fila; }
public int GetColumn(int index) { int col = ndice % numOfColumns; retorno col; }
Otro mtodo importante es GetNeighbors, que es utilizado por la clase AStar a recu
perar los nodos vecinos de un nodo concreto:
public void GetNeighbors(node, ArrayList vecinos) { Vector3 neighborPos = node.p
osicin; int(neighborPos GetGridIndex neighborIndex =);
int fila = GetRow(neighborIndex); columna int = GetColumn(neighborIndex);
//int leftNodeRow inferior = fila - 1; int leftNodeColumn = columna; AssignNeigh
bor(leftNodeRow, leftNodeColumn, vecinos);
//Top leftNodeRow = fila + 1; leftNodeColumn = columna; AssignNeighbor(leftNodeR
ow, leftNodeColumn, vecinos);
//derecha = fila; leftNodeColumn leftNodeRow = columna + 1; AssignNeighbor(leftN
odeRow, leftNodeColumn, vecinos);
//Izquierda = fila; leftNodeColumn leftNodeRow = columna - 1; AssignNeighbor(lef
tNodeRow, leftNodeColumn, vecinos); }
[ 130 ]

void AssignNeighbor(int, int Fila columna, vecinos de ArrayList) { if (fila != -


1 &amp;&amp; la columna != -1 &amp;&amp; fila &lt; numOfRows &amp;&amp; columna
&lt; numOfColumns) { nodos nodos nodeToAdd =[fila, columna]; if (!nodeToAdd.bObs
tacle) { vecinos.Add(nodeToAdd); } } } en
primer lugar, recuperamos los nodos vecinos del nodo actual en la Izquierda, Der
echa, Superior e inferior en cuatro direcciones. A continuacin, dentro del mtodo A
ssignNeighbor, comprobamos el nodo para ver si es un obstculo. Si es no, entonces
tenemos que empujar el nodo vecino a la referida lista de matrices, vecinos. El
siguiente mtodo es un mtodo de ayuda de depuracin para visualizar la cuadrcula y el
obstculo bloques.
void OnDrawGizmos() { if (showGrid) { DebugDrawGrid(transform.posicin, numOfRows,
numOfColumns, gridCellSize, Color.blue); } Gizmos.DrawSphere(transform.posicin,
0.5F); if (showObstacleBlocks) { cellSize Vector3 = new Vector3(gridCellSize, 1.
0F, gridCellSize); if (obstacleList != null &amp;&amp; obstacleList.length &gt;
0) { foreach en obstacleList GameObject (datos) { Gizmos.DrawCube(GetGridCellCen
ter( GetGridIndex(data.transform.position), cellSize); } } } }
public void DebugDrawGrid(vector3 origen, int numRows, int numCols,float cellSiz
e, Color color) { float ancho = (numCols * cellSize); altura de flotacin = (numRo
ws * cellSize); // dibujar las lneas de cuadrcula horizontal (int i = 0; i &lt; nu
mRows + 1; i++) { Vector3 Posicin de comienzo = origen + i * cellSize * nuevo Vec
tor3(0.0F, 0.0F, 1.0F); Vector3 final = posicin de comienzo + ancho * nuevo Vecto
r3(1.0F, 0.0F, 0.0F); Debug.DrawLine(posicin de comienzo, final, color); }
[ 131 ]
// dibujar las lneas de cuadrcula vertial for (int i = 0; i &lt; numCols + 1; i++)
{ Vector3 Posicin de comienzo = origen + i * cellSize * nuevo Vector3(1.0F, 0.0F
, 0.0F); Vector3 final = posicin de comienzo + altura * nuevo Vector3(0.0F, 0.0F,
1.0F); Debug.DrawLine(posicin de comienzo, final, color); } } }
Gizmos puede ser usado para dibujar la depuracin visual y ayudas de instalacin den
tro del editor la vista de la escena. Se llama OnDrawGizmos cada fotograma por e
l motor. As, si el lag, depurar y showGrid showObstacleBlocks estn marcadas, acaba
mos de sacar la rejilla con lneas y obstculo cube objetos con cubos. No vamos a ir
a travs del mtodo DebugDrawGrid, que es bastante simple.
Usted puede aprender ms sobre gizmos en la siguiente Unity3D documentacin de refer
encia en Http://docs.unity3d.com//Documentacin/ScriptReference Gizmos.html.
La AStar AStar clase es la clase principal que utilizar las clases a las que se h
an aplicado hasta ahora. Puede volver a la seccin de algoritmo, si desea revisar
esto. Empezamos con nuestro closedList openList y declaraciones que son del tipo
PriorityQueue como se muestra en la AStar.cs ile:
utilizando UnityEngine; using System.Collections;
public class AStar { public static PriorityQueue closedList, openList; a
continuacin, podemos aplicar un mtodo llamado HeuristicEstimateCost para calcular
el costo entre los dos nodos. El clculo es simple. Acabamos ind el vector de dire
ccin entre las dos restando un vector de posicin de otro. La magnitud de este vect
or resultante da la distancia directa desde el nodo actual hasta el nodo objetiv
o.
private static curNode HeuristicEstimateCost flotacin(nodo, el nodo goalNode) { V
ector3 = curNode vecCost.posicin - goalNode.posicin; devolver vecCost.magnitud; }
[ 132 ] a

continuacin, tenemos nuestro principal FindPath mtodo:


public static ArrayList FindPath(nodo, el nodo inicio objetivo) { openList = new
PriorityQueue(); openList.Empuje(inicio); start.nodeTotalCost = 0.0f; start.est
imatedCost = HeuristicEstimateCost(inicio, meta);
closedList = new PriorityQueue(); Node = null;
inicialicemos nuestra listas abiertas y cerradas. Comenzando por el nodo de inic
io, ponemos en nuestra lista abierta. A continuacin, empezamos a procesar nuestra
lista abierta.
Mientras (openList.Length != 0) { node = openList.First(); //Comprobar si el nod
o actual es el objetivo si el nodo (nodo.posicin == meta.posicin) { return Calcula
tePath(node); }
//Crear un ArrayList para almacenar los nodos vecinos vecinos ArrayList = new Ar
rayList();
GridManager.instance.GetNeighbors(node, vecinos);
para (int i = 0; i &lt; vecinos.Count; i++) { Nodo neighborNode = (nodo)vecinos[
i];
if (!closedList.Contains(neighborNode) { float = costo HeuristicEstimateCost(nod
e, neighborNode);
float costototal = node.nodeTotalCost + coste; flotacin HeuristicEstimateCost nei
ghborNodeEstCost =( neighborNode y meta);
neighborNode.nodeTotalCost = Costototal; neighborNode.Parent = nodo; neighborNod
e.estimatedCost costototal = + neighborNodeEstCost;
if (!openList.Contains(neighborNode) { openList.Push(neighborNode); } } }
[ 133 ]
//empuje el nodo actual a la lista cerrada closedList.Push(nodo); //y quitarlo d
e openList openList.Remove(nodo); }
Si (nodo.position Objetivo !=.position) { Debug.LogError("Objetivo no encontrado
"); return null; } volver CalculatePath(node); }
Este cdigo aplicacin se asemeja al algoritmo que hemos discutido previamente, por
lo que puede volver a consultar, si no est claro de ciertas cosas.
1. Obtener el nodo de nuestra openList IRST. Recuerde nuestro openList de nodos
siempre se ordena cada vez que se agregue un nuevo nodo. De modo que el nodo irs
t es siempre el nodo con el mnimo costo estimado para el nodo objetivo.
2. Comprobar si el nodo actual est ya en el nodo objetivo. Si es as, salir del buc
le while y construir la ruta matriz.
3. Crear una lista de matrices para almacenar los nodos vecinos del nodo actual
est procesando. Utilice el mtodo GetNeighbors para recuperar a los vecinos de la c
uadrcula.
4. Para cada nodo de la matriz de los vecinos, debemos comprobar si ya esta en l
a
closedList. Si no, ponerlo en el clculo de los valores de costo, actualice el nod
o Propiedades con los nuevos valores de costo, as como el nodo primario de datos
y ponerla en openList.
5. Empuje el nodo actual para closedList y quitarlo de openList. Volver al paso
1.
Si no hay ms nodos en openList, nuestro nodo actual debe estar en el nodo de dest
ino si existe una ruta de acceso vlida. A continuacin, llamamos al mtodo CalculateP
ath con el nodo actual parmetro.
private static ArrayList CalculatePath(node) { ArrayList list = new ArrayList();
mientras (nodo != null) { list.Add(nodo); = nodo node.padre; } lista.reverse();
return lista; } }
[ 134 ]

El mtodo CalculatePath rastros a travs de cada nodo padre objeto y construye una l
ista de matrices. Da una lista de matrices con nodos desde el nodo de destino pa
ra el nodo de inicio. Porque queremos una ruta desde el inicio de la matriz de n
odo a nodo de destino slo llamamos al mtodo Reverse.
As que esta es nuestra clase AStar. Escribiremos un script de prueba en el cdigo s
iguiente para probar todo esto.
A continuacin, configurar una escena para usarlos.
TestCode clase
esta clase usar la clase AStar ind la ruta desde el nodo inicial al nodo objetivo
, como se muestra en la siguiente TestCode.cs ile:
utilizando UnityEngine; using System.Collections;
public class TestCode : MonoBehavior { private transformar posicin de comienzo, f
inal; Public Node nododeinicio { GET; set; } Public Node goalNode { GET; set; }
public ArrayList;
GameObject pathArray objStartCube, objEndCube; privados de flotacin = 0.0f elapse
dTime; //intervalo de tiempo entre el pathfinding flotacin pblica intervalTime = 1
.0f;
primero debemos configurar las variables que vamos a necesitar para referencia.
La pathArray es almacenar los nodos Matriz devuelta desde el mtodo FindPath AStar
.
void Inicio () { objStartCube = GameObject.FindGameObjectWithTag("Inicio"); = Ga
meObject objEndCube.FindGameObjectWithTag("Final");
pathArray = new ArrayList(); FindPath(); }
void Update () { elapsedTime Tiempo +=.deltaTime; si (elapsedTime &gt;= interval
Time) { = 0.0f elapsedTime; FindPath(); } }
[ 135 ]
En el mtodo de inicio nosotros buscar objetos con las etiquetas de inicio y fin,
e inicializar nuestro pathArray tambin. Estaremos tratando de ind nuestra nueva r
uta en cada intervalo que hemos establecido en nuestra intervalTime en caso de q
ue las posiciones de los nodos inicial y final han cambiado. A continuacin, llama
mos al mtodo FindPath.
void FindPath() { posicin de comienzo = objStartCube.transform; final = objEndCub
e.transform;
Nododeinicio = Nuevo Nodo(GridManager.instance.GetGridCellCenter( GridManager.in
stance.GetGridIndex(posicin de comienzo.position)));
goalNode = Nuevo Nodo(GridManager.instance.GetGridCellCenter( GridManager.instan
ce.GetGridIndex(final.position)));
pathArray = AStar.FindPath(Nododeinicio, goalNode); }
desde que hemos implementado nuestro algoritmo pathinding en la clase AStar, enc
ontrar una ruta se ha convertido en mucho ms simple. En primer lugar, tomamos las
posiciones de inicio y fin de nuestros objetos del juego. A continuacin, creamos
nuevo nodo objetos utilizando los mtodos auxiliares de GridManager,
GetGridIndex, para calcular sus respectivas posiciones de ndice de fila y columna
dentro de la cuadrcula. Una vez que logremos que llamamos al mtodo FindPath AStar
.con el nodo inicial y el nodo objetivo, y almacenar la matriz devuelta en la li
sta propiedad pathArray local.
A continuacin, podemos aplicar el mtodo OnDrawGizmos para dibujar y visualizar la
ruta encontrada.
void OnDrawGizmos() { if (pathArray == null); en
caso de retorno (pathArray.Count &gt; 0) { int index = 1; el mtodo foreach (nodo
nodo pathArray) { if (ndice &lt; pathArray.Count) { Nodo nextNode = (nodo)pathArr
ay[index]; Debug.DrawLine(node.posicin, nextNode.posicin, Color.green); index++; }
} } } }
[ 136 ]

miramos por nuestro pathArray y utilice el mtodo Debug.DrawLine para dibujar las
lneas que conectan los nodos desde el pathArray. Con la que podremos ver una lnea
verde que conecta los nodos desde el inicio hasta el final formando un camino, c
uando queremos ejecutar y probar nuestro programa.
Configurar las escenas
que vamos a configurar una escena que parece algo similar a la siguiente captura
de pantalla:
muestra la escena de prueba
[ 137 ]

tendremos una luz direccional, el inicio y el final del juego los objetos, unos
objetos de obstculo, un avin entidad para ser utilizado como tierra vaca y dos obje
tos del juego en el que colocar nuestros TestAStar GridManager y scripts. Esta e
s nuestra escena jerarqua: la
jerarqua de escena
crea un montn de entidades de cubo y etiquetarlas como obstculo. Estaremos buscand
o objetos con esta etiqueta cuando se ejecuta nuestro algoritmo pathinding.
Nodos de obstculo
[ 138 ]

crear una entidad de cubo y lo etiqueta como inicio.


Nodo de inicio para
crear otra entidad de cubo y lo etiqueta como final.
El nodo final
[ 139 ]

Ahora crear un juego vaco y adjuntar el objeto GridManager script. Defina el nomb
re como GridManager tambin, porque utilizamos este nombre para buscar el objeto G
ridManager desde nuestro script. Aqu podemos configurar el nmero de filas y column
as de la cuadrcula, as como el tamao de cada mosaico.
Script GridManager
[ 140 ]

Las pruebas
vamos a golpear el botn Reproducir y vea nuestro algoritmo A* pathinding en accin.
Por defecto, una vez que juegue la escena Unity3D cambiar a la vista de juego. D
esde nuestra visualizacin pathinding cdigo est escrito para depurar dibujar en la v
ista del editor, tendr que volver a la escena ver o activar Gizmos para ver la ru
ta encontrada.
Encontr una ruta
[ 141 ]

Ahora intente mover el nodo inicial o final en torno a la escena con el editor d
e movimiento de Gizmo. (No en la vista de juego, pero la escena vista.)
encontr dos path
debe ver la ruta actualizado en consecuencia si hay una ruta vlida desde el nodo
inicial al nodo objetivo, dinmicamente en tiempo real. Obtendr un mensaje de error
en la ventana de la consola si no hay ninguna ruta disponible.
Resumen
En este captulo, hemos aprendido cmo aplicar el algoritmo A* pathinding Unity3D en
el medio ambiente. Hemos desarrollado nuestra propia* pathinding clase as como n
uestra propia clase grid, cola de clase y clase de nodo. Aprendimos sobre la int
erfaz IComparable y reemplazando el mtodo CompareTo. Solamos llamar las funciones
de depuracin para visualizar la cuadrcula y la ruta de la formacin. Con Unity3D's n
avagent navmesh y caractersticas que pueden no ser necesarios para implementar es
te algoritmo pathinding por su propia cuenta. Sin embargo, ayuda a entender el a
lgoritmo subyacente detrs de la aplicacin.
En el prximo captulo, veremos cmo ampliar la idea detrs de un* y mire las mallas de
navegacin. Con mallas de navegacin, ser mucho ms fcil para nosotros ind un camino sob
re terrenos irregulares.
[ 142 ] La
malla de navegacin
en este captulo, vamos a aprender a utilizar la unidad de navegacin incorporada de
l generador de mallas que pueden hacer que la ruta para encontrar agentes de IA
mucho ms fcil. Desgraciadamente, esta caracterstica slo est disponible en la unidad P
ro, por lo que necesitas tener una licencia. O bien, puede empezar a utilizar la
prueba gratuita de 30 das de la unidad Pro (si no lo has hecho ya) a seguir junt
o con los ejercicios de este captulo. Para activar la prueba gratuita, desplcese h
asta la unidad | Administrar Licencia... y seleccione Activar la nueva licencia.
Verificar la prueba gratuita de 30 das de opcin y, a continuacin, haga clic en Ace
ptar, y usted debe ser bueno para ir.
Activacin de prueba gratuita de Unity Pro

Introduccin
ruta AI dentificacin necesita la representacin de la escena en un formato particul
ar. Hemos visto que el uso de una cuadrcula 2D (matriz) para una ruta* dentificac
in en un mapa 2D. Agentes de ia necesidad de saber dnde estn los obstculos, especial
mente los obstculos estticos. Tratar con la evitacin de colisiones entre objetos en
movimiento dinmicamente es otro asunto, principalmente conocida como comportamie
ntos de direccin. La unidad incorpora una funcin de navegacin para generar una mall
a de navegacin (navmesh) que representa la escena en un contexto que tiene sentid
o para nuestros agentes de IA para ind el camino ptimo hacia el destino. Este capt
ulo viene con una unidad de proyecto que tiene cuatro escenas. Usted debe abrirl
o en la unidad y ver cmo funciona para conseguir una sensacin de lo que vamos a co
nstruir. Mediante este proyecto de muestra, y estudiaremos cmo crear un navmesh,
y utilizarlo con agentes de IA dentro de nuestras propias escenas.
Configurar el mapa
para empezar, vamos a construir una escena sencilla, como se muestra en el sigui
ente grfico. Esta es la primera escena en nuestro proyecto de muestra denominado
NavMesh01-Simple.escena. Puede utilizar un plano como un objeto de masa y varias
entidades de cubo como objetos de la pared. Ms tarde, vamos a poner en algunos a
gentes de IA (por supuesto, nuestro favorito de todos los tiempos los tanques) p
ara ir a la posicin de clic del ratn, como en un juego de RTS.
Escena con obstculos-NavMesh01-Simple.Scene
[ 144 ]

esttica de navegacin
una vez que hemos aadido las paredes y el suelo, es importante para marcarlos com
o navegacin esttica, por lo que el generador de navmesh sabe quienes son el obstcul
o para evitar objetos estticos. Para ello, seleccione todos los objetos, haga cli
c en el botn esttico, y elija la navegacin esttica, como se muestra en el siguiente
grfico.
La propiedad esttica navegacin
hornear la malla de navegacin
ahora hemos terminado con nuestra escena. Vamos a cocer los navmesh. En primer l
ugar, tenemos que abrir la ventana de navegacin. Vaya a la ventana | Navegacin, y
usted debera ser capaz de ver una ventana como esta:
ventana de navegacin
[ 145 ]
todas estas propiedades son bastante autoexplicativas y puedes echar un vistazo
a la siguiente unidad de documentacin de referencia para ms informacin:
Manual/Navmeshbaking http://docs.unity3d.com/Documentation/.html
por ahora, saldremos con los valores predeterminados y haga clic en cocer. Usted
debe ver una barra de progreso de hornear el navmesh para su escena, y despus de
un tiempo, usted ver su navmesh en la escena, como se muestra en el siguiente di
agrama.
Malla de navegacin
Nav horneados agente malla
somos bastante mucho con la configuracin de nuestro super simple escena. Ahora, v
amos a agregar algunos agentes de IA para ver si funciona. Usaremos nuestro tanq
ue modelo aqu. Pero si ests trabajando con su propio escenario y no tienen este mo
delo, usted puede poner un cubo o una esfera de entidad como un agente. Funciona
ra de la misma manera.
[ 146 ]

entidad de depsito
El siguiente paso es agregar el componente de agente de malla Nav depsito a nuest
ra entidad. Este componente hace camino dentificacin realmente fcil. No tenemos qu
e lidiar con la ruta dentificacin algoritmos como un* ms. Simplemente mediante la
configuracin de la propiedad Destino del componente en tiempo de ejecucin, nuestro
agente AI ind automticamente el trazado.
Desplcese al componente | Navegacin | Agente de malla de Nav para agregar este com
ponente.
Propiedades del Agente de malla Nav
unidad referencia para Nav componente de agente de malla puede ser encontrada en
http://docs.unity3d.com/Documentation/ componentes/clase-NavMeshAgent.html
una propiedad a tener en cuenta es la propiedad NavMesh pisable. Este navmesh sp
eciies las capas que este agente navmesh puede caminar. Hablaremos de navegacin e
n la seccin NavMeshLayers capas.
[ 147 ]

Actualizar destinos los agentes


ahora hemos creado nuestro agente de AI, necesitamos una manera de decirle a est
e agente a dnde ir y actualizar el destino de nuestros tanques para el clic del r
atn.
Por lo tanto, vamos a aadir una esfera de entidad a la que se utiliza como marcad
or objeto y, a continuacin, adjuntar el siguiente destino.cs script a un objeto j
uegos vaca. Arrastre y suelte este mbito en esta entidad targetMarker del script e
n el inspector de propiedades de transformacin.
El objetivo.cs
esta clase es una clase simple que hace tres cosas:
Obtiene el clic del ratn la posicin mediante un rayo actualiza la posicin del marca
dor actualiza la propiedad de destino de todos los agentes navmesh
las lneas siguientes muestran el cdigo presente en esta clase:
utilizando UnityEngine; using System.Collections;
public class Target : MonoBehavior {[] navAgents NavMeshAgent privado; Transform
acin pblica targetMarker;
void Start() { navAgents = FindObjectsOfType(typeof(NavMeshAgent) como NavMeshAg
ent[]; }
void UpdateTargets(vector3) { targetPosition (agente NavMeshAgent foreach en nav
Agents) { agent.Destino = targetPosition; } }
void Update() { botn int = 0;
//Obtener el punto de la posicin de golpe cuando el ratn es //haciendo clic si(Inp
ut.GetMouseButtonDown(Button) { Ray ray = Cmara.main.ScreenPointToRay( Input.mous
ePosition); RaycastHit hitInfo;
[ 148 ]

Si (Fsica.Raycast(ray.Origen, Ray.direccin, Fuera hitInfo) { = hitInfo targetPosit


ion Vector3.El punto; UpdateTargets(targetPosition); targetMarker.posicin = targe
tPosition + nuevo Vector3(0,5,0); } } } }
al comienzo del juego, esperamos que todas las entidades de tipo NavMeshAgent en
nuestro juego y almacenarlos en nuestra referencia NavMeshAgent matriz. Siempre
que hay un evento de clic de ratn-, hemos de hacer un simple raycast irst para d
eterminar los objetos que chocan con nuestro rayo. Si el rayo golpea cualquier o
bjeto, actualizamos la posicin de nuestro marcador y actualizar cada destino del
agente navmesh estableciendo la propiedad de destino con la nueva posicin. Vamos
a utilizar este script a lo largo de este captulo para indicarle la posicin de des
tino para nuestros agentes de IA.
Ahora, prueba la escena y, a continuacin, haga clic en el punto donde desea que s
us tanques para ir.
Los tanques deben acercarse lo ms posible a ese punto evitando los obstculos esttic
os como paredes.
Escena con pendiente
construyamos una escena con algunas pendientes como este:
Escena con laderas-NavMesh02-slope.Scene
[ 149 ]

Una cosa importante a tener en cuenta es que las laderas y la pared debe estar e
n contacto unos con otros. Los objetos deben estar perfectamente conectados al c
rear tales articulaciones en la escena con el objetivo de generar una navmesh po
steriormente. De lo contrario, habr lagunas en navmesh y los agentes no podrn ind
el camino ya. Hay una caracterstica llamada Off generacin Enlaces de malla para re
solver este tipo de problema. Echaremos un vistazo a los enlaces de malla Off en
la seccin Enlaces de malla ms adelante en este captulo. Por ahora, asegrese de cone
ctar la pendiente correctamente.
Bien conectado pendiente
siguiente, podemos ajustar la pendiente mxima de la propiedad en la ventana de na
vegacin de hornear ficha de acuerdo con el nivel de la pendiente en nuestras esce
nas que queremos permitir que los agentes de viajes.
Usaremos 45 grados aqu. Si sus laderas son ms pronunciados que esto, puede usar un
mayor
valor de la pendiente mxima.
Propiedad de pendiente mxima
Hornee la escena, y debera haber un navmesh generado como esto:
Nav Mesh generado
[ 150 ]
prximo, vamos a colocar algunos tanques con el componente de agente de malla de N
av. Crear un cubo nuevo objeto para ser utilizado como un objetivo la posicin de
referencia. Utilizaremos nuestro
objetivo anterior.cs script para actualizar la propiedad Destino de nuestro agen
te de AI. Comprobar el funcionamiento de la escena, y usted debe tener sus agent
es de IA cruzar las laderas para llegar a la meta.
NavMeshLayers
en juegos con entornos complejos, normalmente tenemos algunas reas que son ms difci
les para los viajes en que otras, tales como un estanque o un lago frente a cruz
ar un puente.
Aunque podra ser el camino ms corto hacia el objetivo por cruzar el estanque direc
tamente, nos gustara que nuestros agentes para elegir el puente que tiene ms senti
do. En otras palabras, queremos hacer cruzar el charco para ser ms costoso que na
vigationally usando el puente. En esta seccin veremos NavMeshLayers, una manera d
e deine diferentes capas con diferentes valores de costo de navegacin.
Vamos a construir una escena como se muestra en el siguiente grfico. Habr tres pla
nos para representar dos planos de tierra conectado con un puente-como estructur
a y un plano de agua entre ellos. Como puede ver, es la ruta ms corta para nuestr
o tanque para cruzar el plano de agua para alcanzar nuestra meta de cubo. Pero q
ueremos que nuestros agentes de IA para elegir el puente si es posible y para cr
uzar el plano de agua slo si es absolutamente necesario, como cuando el objeto de
destino est en el plano de agua.
Escena con capas-NavMesh03-capas.Scene
[ 151 ]

La escena jerarqua puede verse en la siguiente captura de pantalla. Nuestro nivel


de juego se compone de aviones, cuestas y muros. Tenemos un tanque de entidad y
un cubo de destino con el objetivo.cs script asignado.
Jerarqua de escenas
para crear su propio NavMeshLayer, vaya a Editar | Configuracin del proyecto | Na
vMeshLayers.
NavMeshLayers
[ 152 ] La

unidad de referencia para Nav Capas de malla puede ser encontrada en http://docs
.unity3d.com/Documentation/ componentes/clase-NavMeshLayers.html
unidad viene con tres capas por defecto: Por defecto, no se poda ir andando, y sa
ltar, cada uno con valores de costo potencialmente diferentes. Vamos a aadir una
nueva capa llamada "Agua y darle un costo de 5.
A continuacin, seleccione el plano de agua. Vaya a la ventana de navegacin y bajo
la ficha Objeto, defina la navegacin a la capa de agua.
La capa de agua
Cueza los navmesh para la escena, y ejecutarlo para probarlo. Usted debe ver que
los agentes de IA ahora elegir la pendiente en lugar de atravesar el plano marc
ado como la capa de agua porque es ms caro para elegir ese camino. Experimente co
n colocar el objeto de destino en diferentes puntos en el plano de agua. Ver que
los agentes de IA a veces nadar de vuelta a la orilla y tomar el puente, en luga
r de intentar nadar todo el camino a travs del agua.
Off Enlaces de malla
a veces podra haber algunas lagunas dentro de la escena que pueden hacer que las
mallas de navegacin desconectado. Por ejemplo, nuestros agentes no podrn ind la ru
ta si las pistas no estn conectados a las paredes en nuestros ejemplos anteriores
. O podramos haber establecido puntos donde nuestros agentes pueden saltar de la
pared y en el plano siguiente. La unidad dispone de una funcin denominada Off Enl
aces de malla para conectar esas lagunas. Off Enlaces de malla puede ser configu
rada manualmente o generados automticamente por la Unidad navmesh del generador.
[ 153 ]

Aqu est la escena de ejemplo que vamos a construir en este ejemplo. Como puede ver
, hay una pequea diferencia entre los dos planos. Vamos a ver cmo conectar estas d
os aviones utilizando enlaces de malla.
Escena con enlaces de malla off-NavMesh04-OffMeshLinks.scene
generado Off Enlaces de malla
en primer lugar, utilizaremos autogenerada malla Off enlaces para conectar los d
os aviones. La primera cosa a hacer es marcar estos dos planos como Off malla ge
neracin enlace esttico en el inspector de propiedades, como se muestra en la sigui
ente captura de pantalla:
Off Link malla esttica generacin
[ 154 ]

Ir a la ventana de navegacin y observe las siguientes propiedades en la pestaa de


hornear. Puede establecer la distancia umbral a autogenerate Off Enlaces de mall
a.
Generado Malla Off Links propiedades
Haga clic en cocer, y debera haber apagado la malla vnculos que conectan los dos a
viones como este:
Genera vnculos de malla Off
Ahora nuestros agentes de IA pueden recorrer la ruta e ind en ambos planos. Los
agentes sern esencialmente teletransportado a otro plano, una vez que han alcanza
do el borde del avin y encontr el enlace de malla. Por supuesto, si teletransporta
ndose agentes no son lo que queremos, es mejor colocar un puente para que los ag
entes pudieran cruzar.
[ 155 ]

Enlaces de malla desactivado manual


si no queremos generar Off Enlaces de malla a lo largo del borde, y queremos for
zar a los agentes para llegar a un punto determinado a ser teletransportado a ot
ro plano, tambin podemos configurar manualmente el Off Enlaces de malla. He aqu cmo
:
Enlaces de malla manual fuera de configuracin
Esta es nuestra escena con una signiicant brecha entre dos planos. Hemos colocad
o dos pares de la esfera de las entidades de ambos lados del avin. Elija una esfe
ra, y aadir un enlace de malla desplazndose al componente | Navegacin | Off Link de
malla. Slo tenemos que agregar este componente en una esfera. A continuacin, arra
strar y soltar el irst esfera a la propiedad Start, y la otra esfera a la propie
dad End.
Desactivar el componente de enlace de malla
[ 156 ] La
unidad de referencia para desactivar enlaces de malla puede ser encontrada en ht
tp://docs.unity3d.com/Documentation/ componentes/clase-OffMeshLink.html.
Malla manual fuera de los vnculos generados
vaya a la ventana de navegacin y hornee la escena. Los aviones estn ahora conectad
as con la malla manual fuera de enlaces que pueden ser utilizados por agentes de
IA para atravesar aunque hay una brecha.
[ 157 ]

Resumen
En este captulo, hemos aprendido cmo generar y utilizar mallas de navegacin para re
presentar la escena para la ruta dentificacin propsitos. Hemos estudiado cmo config
urar diferentes capas de navegacin con costos diferentes para encontrar la ruta.
Hemos utilizado el componente de agente de malla Nav ind fcilmente el camino y av
anzar hacia el objetivo utilizando la
propiedad de destino. Hemos creado enlaces de malla Off para conectar las brecha
s entre las mallas de navegacin utilizando tanto la autogeneracin caracterstica y m
anual con el componente de enlace de malla. Con toda esta informacin, ahora podem
os crear fcilmente juegos sencillos con AI bastante complicado. Por ejemplo, uste
d puede intentar establecer la propiedad Destino de AI tanques a la posicin del d
epsito del jugador y hacerlos respetar. Y, utilizando una simple FSMs, pueden emp
ezar a atacar al jugador una vez que llegan a una cierta distancia. Nuestro FSM
nos ha llevado lejos, pero tiene sus lmites. En el prximo captulo, vamos a aprender
sobre el comportamiento de los rboles, y cmo se pueden usar para hacer decisiones
de AI en incluso el ms complejo de los juegos.
[ 158 ] el

comportamiento el
comportamiento de los rboles Los rboles son otra forma de control de los estados y
los comportamientos de nuestros personajes. Tambin son una alternativa a las mqui
nas de estado inite (FSM), que se describi en el Captulo 2, mquinas de estado finit
o. Aunque FSMs son sencillas de implementar, intuitivo y fcil de comprender, es d
ifcil de mantener y ampliar una vez que la lgica se vuelve muy complejo. Una de la
s razones de esto es que en mquinas de estado, todas las transiciones entre los E
stados tienen que ser precisamente deined. As, como el tamao de la mquina de estado
se vuelve ms grande, la actualizacin de la estructura de una mquina de estado con
todas las transiciones se torna extremadamente compleja. Para los desarrolladore
s de AI se han trasladado a ind nuevas formas y otras tcnicas, tales como el FSM
(HFSM jerrquica) y redes (HTNs jerrquica de tareas). Los rboles son el comportamien
to de uno de ellos que se han popularizado con el uso de AAA juegos como Halo, C
rysis, y espora.
Dado que este libro est centrado en la aplicacin de IA en Unity3D, no cubriremos a
plicar todo el comportamiento del sistema de rbol desde cero. Afortunadamente, ex
iste un poderoso llamado plugin comportarse para Unity3D para implementar un com
portamiento de rboles. As que vamos a estar usando en este captulo, as como el estud
io de los componentes y las ideas generales de comportamiento rboles mientras la
aplicacin demostraciones sencillas.
Se comportan de plugin
se comportan es un sistema para Unity3D para el diseo de objetos del juego usando
la lgica de comportamiento el comportamiento de los rboles. Fue diseado y desarrol
lado por Emil Johansen ("AngryAnt"), quien actualmente trabaja en la Unidad de t
ecnologas. Se comportan el sistema viene con un simple y fcil de usar de arrastrar
-y-soltar logic diseador. Los diseadores del juego puede usar esta interfaz para c
onfigurar el comportamiento logic mientras los desarrolladores implementar las a
cciones reales. Desde su sencilla herramientas para implementar un comportamient
o de rboles en Unity3D, estaremos utilizando este sistema para implementar el com
portamiento de los agentes en este captulo.
Los siguientes son los pasos que se deben realizar para la descarga e instalacin
de comportarse:
1. En primer lugar, Let's go y descargar comportarse de la unidad tienda de acti
vos. Dentro de Unity3D, vaya a la ventana | Tienda de activos y, a continuacin, bs
queda de comportarse.
2. Una vez ind comportarse, haga clic en la flecha situada junto al botn de desca
rga y elija descargar e importar. Esto descargar el sistema se comportan e import
arlos a su actualmente abierto Unity3D proyecto. La ltima versin de comportarse es
la versin 1.4, y es gratis. Por lo tanto, estaremos utilizando esta versin. Si es
ts usando una versin anterior, podra haber mayores o menores cambios y el cdigo no p
uede trabajar fuera de la caja.
Comportarse en la tienda de activos
[ 160 ]

3. Una vez que hayas importado se comportan en su proyecto ver una carpeta denomi
nada comportarse en el directorio del proyecto.
La biblioteca se comportan importado
realmente usted no necesita preocuparse de cualquiera de los contenidos de esta
carpeta. Una vez ah, estamos dispuestos a utilizar el sistema.
Vamos a mirar briely del flujo de trabajo en la asamblea del flujo de trabajo us
o de comportarse para implementar un comportamiento de rboles. Despus veremos cmo f
unciona cada componente individualmente, vamos a poner los pedazos juntos y crea
r una demostracin de robots y los extranjeros. Comencemos realizando los siguient
es pasos:
[ 161 ]

1. Para utilizar el sistema se comportan, nos irst necesita crear una biblioteca
se comportan. As que vamos a crear uno ahora, y llamarlo AgentBehaveLib .
Crear un nuevo comportarse de la biblioteca
2. Seleccione su biblioteca se comportan AgentBehaveLib recin creada y haga clic
en Editar en el inspector de propiedades de la biblioteca.
Una biblioteca se comportan propiedades
[ 162 ]
3. El panel Navegador se comportan aparecer como se muestra en la siguiente captu
ra de pantalla. Aqu puede crear colecciones que mantenga el comportamiento real d
e los rboles.
Crear nueva coleccin
4. Crear una nueva coleccin. Deje el nombre predeterminado. Entonces, mientras qu
e esta coleccin es seleccionado, crear un nuevo rbol. Deje el nombre predeterminad
o aqu tambin. Su navegador se comportan debe parecerse a la siguiente captura de p
antalla:
Comportarse navegador
5. Seleccione el rbol de comportamiento que acaba de crear y en la ventana del ed
itor se comportan debe tener un aspecto similar a la siguiente captura de pantal
la. Si no puede ver el editor, vaya a la ventana de rbol se comportan | editor pa
ra activarlo.
[ 163 ]

hay seis elementos bsicos en la creacin de rboles de comportamiento. Es mejor usar


un estilo tutorial para estudiarlos. Por lo tanto, empecemos con la accin de los
nodos.
Editor de rbol se comportan de
Accin
Las acciones son la ms bsica de los nodos que se ejecute realmente algo en el comp
ortamiento de los rboles.
Vamos a crear una nueva accin arrastrando el nodo action se comportan en el edito
r. A continuacin, enlace con el nodo raz haciendo clic y arrastrando el nodo raz ha
sta el enlace los ganchos en la parte superior de la caja del nodo action. Accin
con el nodo seleccionado, cambie el nombre de la accin desde el inspector MyActio
n como se muestra en la siguiente captura de pantalla. Esta configuracin se compo
rtan bsicamente le dice al sistema que este comportamiento rbol va a ejecutar esta
accin mixta un nmero de veces en un segundo (como siempre en la frecuencia variab
le de la propiedad Node). Asegrese de configurar el valor de frecuencia a algo di
stinto de cero, por lo que las funciones creamos ms tarde realmente ser llamado. T
ambin puede ind clase adicional informacin de referencia dentro del panel del insp
ector de propiedades.
[ 164 ] La

accin propiedades de nodo


si configura las propiedades del nodo de accin en consecuencia, su diagrama de rbo
l debera buscar algo, como se muestra en la siguiente captura de pantalla:
Una accin nodo
[ 165 ] La

interconexin con el script


antes de que podamos acceder a este comportamiento rbol a partir de una secuencia
de comandos que necesitamos para crear o compilar este comportamiento de rbol. S
e comportan compilar el rbol a una DLL de manera que podamos hacer referencia y ap
licar nuestras propias acciones personalizadas de nuestros scripts. Es important
e sealar que siempre que se cambie nada dentro de la biblioteca, tendremos que vo
lver a compilar la biblioteca antes que nosotros tratamos de usar lo que hemos aa
dido. Existen dos opciones para crear una biblioteca se comportan de Debug o Rel
ease. Estas opciones de construccin slo se aplican a nuestra biblioteca y no se co
mportan a nuestro juego real. Vamos a utilizar la versin de depuracin en este tuto
rial que nos permitir depurar nuestro comportamiento rboles utilizando comportarse
incorporadas en Visual Debugger.
As, para compilar su comportamiento simplemente seleccione el rbol se comportan de
biblioteca (en este caso
AgentBehaveLib) y, a continuacin, haga clic en Biblioteca de compilacin debug desd
e el panel Inspector.
Despus de un momento vers dos nuevos iles se agregan al directorio del proyecto. P
uede que necesite actualizar su carpeta de proyecto para ver los cambios. Con es
a biblioteca construida correctamente ahora estamos listos para implementar las
acciones en nuestro script. As que vamos a crear un nuevo script de C# y llamarlo
AgentController.
La primera cosa que necesitamos hacer es importar comportarse de biblioteca en t
iempo de ejecucin que puede encontrarse en el espacio de nombres se comportan.Run
time. Y tenemos que implementar la interfaz IAgent deined por el sistema se comp
ortan de manera que podemos manejar nuestras propias acciones.
El cdigo en el AgentController.cs ile es como sigue:
Usando UnityEngine; using System.Collections; uso de comportarse.Runtime; usando
= rbol comportarse.Runtime.Tree;
public class AgentController : MonoBehavior, IAgent {
Tree m_Tree;
luego declaramos una variable de rbol para hacer referencia a nuestro comportamie
nto de rbol. A continuacin, dentro de nuestro
mtodo Start, usamos el mtodo esttico InstantiateTree de nuestra biblioteca para cre
ar una instancia de nuestro comportamiento de rbol. La biblioteca BLAgentBehaveLi
b es generado por comportarse con este patrn de nomenclatura, BL{YourLibraryName}
. Se comportan utiliza ese tipo de convencin de nomenclatura, como ver ms adelante,
y es importante mantener los nombres en la forma que necesita. El mtodo Instanti
ateTree acepta dos parmetros: el tipo de rbol para crear instancias y la referenci
a a una clase que implementa la interfaz IAgent, en nuestro caso acabamos de pas
ar en esta para consultar la clase actual. Observe que el tipo de rbol es una com
binacin de lo que llamamos nuestra coleccin y lo que llamamos nuestro rbol.
IEnumerator Inicio () { m_Tree =( BLAgentBehaveLib BLAgentBehaveLib.InstantiateT
ree.TreeType.NewCollection1_NewTree1, este);
[ 166 ]

mientras (Application.isPlaying &amp;&amp; m_Tree != null) { return new WaitForS


econds rendimiento(1.0f/m_Tree.frecuencia); AIUpdate(); } }
comportarse tiene un bucle en tiempo real que requiere nuestro propio mtodo updat
e, AIUpdate es el mtodo de actualizacin que hemos creado y es llamado en un interv
alo particular basado en la propiedad de frecuencia speciied en nuestro rbol. Den
tro de nuestro mtodo AIUpdate slo llamamos al mtodo de graduacin de nuestra instanci
a de rbol. [Nota: Comportarse utiliza el trmino tick en lugar de actualizar.]
void AIUpdate() { m_Tree.Tick(); }
Hay tres mtodos que debemos aplicar para nuestra interfaz IAgent. Son como sigue:
BehaveResult Tick (rbol de remitente, bool init); void Reset (rbol); int SelectTop
Priority remitente (Sender, rbol params id int[]);
as que vamos a aplicarlas. La garrapata y restablecer mtodos se llama cuando una a
ccin o un decorador (de lo que hablaremos ms adelante), es decir, bien marcada o r
establecer. Si hemos aplicado nuestros propios mtodos de controlador para nuestra
s acciones, estos mtodos se utilizar en su lugar:
pblico BehaveResult Tick(Tree remitente, bool init) { Debug.log("marcada recibida
por unhandled " + (BLAgentBehaveLib.IsAction(sender.ActiveID) ? "Accin " :
"decorador " + " ... " + (BLAgentBehaveLib.IsAction(sender.ActiveID) ?
((BLAgentBehaveLib.ActionType)remitente.ActiveID).ToString() :
((BLAgentBehaveLib.DecoratorType)remitente.ActiveID).ToString())); return Behave
Result.xito; }
public void Reset (rbol de remitente) {
}
[ 167 ]

dentro de nuestro mtodo Tick genrico, que acabamos de imprimir el nombre de la acc
in o el decorador nodo desde el parmetro sender que recibe esta garrapata, como si
gue:
public int SelectTopPriority (rbol, params Sender ID int[]) { return 0; } }
otra vez, volveremos a este mtodo SelectTopPriority en un corto tiempo. Ahora, va
mos a intentar ejecutar este comportamiento. Acaba de crear un objeto de juego v
aco y adjuntar este
script AgentController. A continuacin, pulsar el botn de reproducir. Si usted sigu
e junto con toda esta seccin, usted debera ser capaz de ver los mensajes de regist
ro de Niza en la consola como se muestra en la siguiente captura de pantalla:
resultados de la accin no controlada
lo que eso significa es ahora nuestro comportamiento tree est trabajando junto co
n nuestro script. Pero como hemos mencionado antes, ya que no tenemos nuestro pr
opio controlador para el nodo MyAction, el mtodo se llama Tick predeterminado y e
s imprimir este mensaje. Volvamos entonces a nuestra secuencia de comandos y esc
ribir nuestra propia funcin de controlador para el nodo MyAction, tal como se ind
ica en el siguiente cdigo:
Public BehaveResult TickMyActionAction rbol (remitente) { Debug.log ("MyAction ma
rcada!"); return BehaveResult.xito; }
para implementar su propio controlador de accin solo tienes que seguir este patrn
de nomenclatura speciic, BehaveResult Tick{name} rbol de accin (remitente). En est
e ejemplo, {nombre} es el nombre de nuestra accin, MyAction. Ahora si reproduce e
l proyecto, ver el mensaje de registro impreso por su propio controlador de accin
como sigue:
Accin resultados
[ 168 ]

con que usted debe tener una comprensin bsica de cmo utilizar comportarse. A contin
uacin vamos a pasar a otros elementos que se utilizan para controlar la ejecucin d
e las acciones bajo el rbol en nuestro comportamiento.
Decorador
decoradores permiten una entrada condicional antes de ejecutar cualquier nodo co
nectado a ella.
Controladores personalizados para los decoradores pueden aplicarse de la misma m
anera que hicimos para acciones previamente, pero siguiendo el patrn de nomenclat
ura de garrapata BehaveResult{name} rbol Decorator (remitente). Si no hay ninguno
, el valor predeterminado deined mtodo Tick en
IAgent deined ser utilizado. As, vamos a configurar nuestro comportamiento en un n
uevo rbol o sustituir el rbol que tenamos antes con un decorador nodo, como se mues
tra en la siguiente captura de pantalla. Si crea un nuevo rbol, asegrese de actual
izar la variable TreeType BLAgentBehaveLib.en nuestra
funcin de inicio hasta el punto de cualquier rbol que est utilizando. Lo que querem
os hacer es si nuestra nueva decoracin, ShouldDoMyAction, devuelve SUCCESS, vamos
a ejecutar la accin MyAction. De lo contrario, vamos a no ejecutar MyAction.
Decorador
el mtodo controlador deined est basado en los siguientes procedimientos:
Si TickDecorator devuelve SUCCESS, el nio del decorador estar marcada y el decorad
or devolver el resultado de esa garrapata
Si TickDecorator devuelve FAILURE, el nio del decorador no estar marcada y el deco
rador devolver el xito, lo que significa que se ha finalizado la tarea
Si TickDecorator Regresa corriendo, el nio ser marcada y independientemente del re
sultado de esta garrapata, el decorador volver ejecutando
[ 169 ]

Ahora, vamos a escribir nuestro propio mtodo de controlador de eventos para el de


corador ShouldDoMyAction.
Por favor tenga en cuenta que el nombre del mtodo debe ser TickShouldDoMyActionDe
corator como sigue:
private bool shouldDo = true;
pblico TickShouldDoMyActionDecorator BehaveResult rbol (remitente) { shouldDo = !s
houldDo; si (shouldDo) { Debug.log ("Debe Hacer!"); return BehaveResult.xito; } e
lse { Debug.log ("No!"); return BehaveResult.Fallo; } }
Si ejecuta este script, ver si el decorador devuelve SUCCESS el nodo secundario t
ambin se llama y ver el mensaje de registro impreso por el mtodo de controlador Tic
kMyActionAction, como se muestra en la siguiente captura de pantalla:
Decorador resultados
[ 170 ]

se comportan depurador
podemos utilizar comportan el depurador integrado para visualizar el rbol unidos
en vivir si queremos construir nuestra biblioteca se comportan para la depuracin.
As que vamos a examinar el estado de nuestro decorador en live usando este depur
ador. En primer lugar, reproduce el proyecto y vaya a la ventana | comportarse d
epurador para mostrar la ventana del depurador. En la parte superior de la venta
na, ver un rbol instancias etiqueta. Cuando jugamos en la escena, el nombre del rbo
l actualmente cargada aparecer a la derecha de esta etiqueta. Haga clic en el nom
bre del rbol para hacer el rbol aparecen dentro de la ventana del depurador, como
se muestra en la siguiente captura de pantalla:
Comportarse depurador
[ 171 ]

secuencia
secuencias se marque cada uno de sus nodos secundarios conectados de a uno por v
ez, de izquierda a derecha. La colocacin de los nodos es irrelevante. Los nodos q
ue sale de la parte inferior de la secuencia para determinar el orden. Si devuel
ve FAILURE, un nio la secuencia tambin devuelve Failure desde ese punto. Pero si e
l nio devuelve SUCCESS, la secuencia se desplazar a la siguiente lnea infantil y, a
continuacin, regresa corriendo. Vamos a configurar un rbol con una secuencia de n
odos y conectar tres acciones, FadeOut y FadeIn GotoGame.
Secuencia
tres mtodos de controlador para nuestras acciones estn implementadas, y nosotros s
implemente volver
BehaveResult.El xito de la siguiente manera:
public BehaveResult TickFadeInAction rbol (remitente) { Debug.log ("FadeIn marcad
a!"); return BehaveResult.xito; }
pblico TickFadeOutAction BehaveResult rbol (remitente) { Debug.log ("FadeOut marca
da!"); return BehaveResult.xito; }
pblico TickGotoGameAction BehaveResult rbol (remitente) { Debug.log ("GotoGame mar
cada!"); return BehaveResult.xito; }
[ 172 ]

Si se ejecuta el proyecto ahora, ver las tres acciones discutidas anteriormente e


stn obteniendo llama secuencialmente.
Si un nio regresa corriendo, la secuencia tambin devolver ejecutando desde ese punt
o y ese mismo nio estar marcada la prxima vez la secuencia est marcada.
Una vez que la secuencia alcanza el final de la lista de hijos, devuelve el xito
y el irst nio en la lnea ser marcada en la siguiente marca de la secuencia.
Explorar comportan resultados
ahora vamos a actualizar nuestros mtodos de controlador para jugar con otros se c
omportan de resultados. Aumentaremos el valor alfa durante el FadeIn accin, y has
ta que llegue a 255, vamos a volver corriendo de la accin FadeIn como se indica e
n el siguiente cdigo:
private int alfa = 0; int privado gameLoading = 0;
public BehaveResult TickFadeInAction rbol (remitente) { if (gameLoading &gt;= 100
) { return BehaveResult.Fallo; }
alpha++; Debug.log ("FadeIn marcada! Alfa:" + alpha.ToString()); si (alfa &lt; 2
55) { return BehaveResult.Funcionando; } else { alfa = 255; retorno BehaveResult
.xito; } }
entonces, la secuencia no se mover al siguiente nio y mantendr FadeIn tictac esta a
ccin. Slo cuando el alfa alcanza a 255, esta accin devolver el xito y la secuencia se
mover hasta el siguiente nodo secundario. Una vez que hayamos alcanzado la accin
GotoGame gameLoading y hasta que el progreso ha alcanzado 100 vamos a devolver sl
o el
fracaso, de modo que no se iniciar esta secuencia nuevamente hasta que la carga e
st completa.
[ 173 ]

La siguiente accin es la accin FadeOut y va a disminuir el valor de alfa. Similar


a
FadeIn, hasta llegar a 0, vamos a devolver slo ejecuta. As, la secuencia tambin reg
resar en
marcha y cuando la secuencia es marcada la prxima vez, va a marcar a partir de es
ta accin. Esto es algo que note con el resultado de que se reanudar a partir de es
e nodo hijo y no desde la izquierda-la mayora de los nios.
pblica BehaveResult TickFadeOutAction rbol (remitente) { alfa--; Debug.log ("FadeO
ut marcada! Alfa:" + alpha.ToString()); si (alfa &gt; 0) { return BehaveResult.F
uncionando; } else { alfa = 0; retorno BehaveResult.xito; } }
finalmente cuando la accin FadeOut devuelve SUCCESS, la secuencia va a pasar a la
accin GotoGame gameLoading y aumentar el valor. Cuando este valor alcanza
100, volveremos el xito, de lo contrario, vamos a devolver slo en marcha, como se
indica en el cdigo siguiente:
public BehaveResult TickGotoGameAction rbol (remitente) { gameLoading++; Debug.lo
g ("GotoGame marcada! Cargando juego: " + gameLoading.ToString()); if (gameLoadi
ng &lt; 100) { return BehaveResult.Funcionando; } else { return BehaveResult.xito
; } }
simplemente utilizamos los tres se comportan de resultados, el xito y el fracaso,
y se ejecuta en el ejemplo anterior. Antes de probar esto, necesitamos aumentar
la
frecuencia temporal de valor (por ejemplo, 25). De lo contrario tomar 10 minutos
para nuestra secuencia al completo! Ahora, pasemos a otros elementos de rbol de c
omportamiento.
[ 174 ]

Selector
Los selectores son como las instrucciones if anidadas y marque cada uno de sus h
ijos una vez al mismo tiempo de izquierda a derecha. Si un nio devuelve SUCCESS,
el selector tambin devuelve el xito desde ese punto. Pero si el nio devuelve FAILUR
E, el selector se mueve al prximo nio en lnea y volver corriendo. Si un nio regresa
corriendo, tambin lo hace el selector y ese mismo nio estar marcada de nuevo la prxi
ma vez que el selector est marcada. Una vez que el selector alcanza el final de l
a lista de hijos, devuelve FAILURE y comienza marcando desde el irst nio nuevamen
te en el siguiente tick del selector.
En este ejercicio, vamos a configurar un rbol como se muestra en la siguiente cap
tura de pantalla, un selector y tres acciones: PATRULLA, Ataque y ralent.
Selector
en accin nuestra patrulla vamos a reducir la distancia con el enemigo variable y
comprobar si es lo suficientemente cerca para este agente. Si no est lo suficient
emente cerca como vamos a devolver simplemente girando el selector y devolver tam
bin ejecutando a partir de este punto, como sigue:
private int distWithEnemy = 200; private int enemyHealth = 100;
pblica BehaveResult TickPatrolAction rbol (remitente) { if (distWithEnemy &gt; 100
) { distWithEnemy-=10;
[ 175 ]

Debug.log("enemigo est obteniendo taponadoras! " + distWithEnemy.


ToString(); return BehaveResult.Funcionando; } else { Debug.log("enemigo manchad
o!"); return BehaveResult.Fallo; } }
Una vez que la variable de distancia es inferior a 100 volveremos fracaso, lo qu
e significa que el enemigo est bastante cerca y no debemos pegar a patrullar la a
ccin ya. Y nuestro selector se mueve al siguiente nodo secundario, que es la accin
de ataque en nuestro caso.
Atacamos a nuestro enemigo y disminuir su salud en nuestra accin de ataque. Mient
ras que durante el ataque se devolver en ejecucin. Y slo cuando el enemigo est muert
o volvemos el
fracaso, lo que significa que nuestro enemigo ahora est muerta y no debemos ataca
r ms.
A continuacin, el selector se mueve al siguiente nodo secundario, que es la accin
de ralent, como sigue:
pblico BehaveResult TickAttackAction rbol (remitente) { enemyHealth-=5; Debug.log(
"ataque enemigo! Salud del enemigo: " + enemyHealth.ToString()); if (enemyHealth
&lt; 10) { Debug.log("enemigo muerto!"); return BehaveResult.Fallo; } else { re
turn BehaveResult.Funcionando; } }
pblico TickIdleAction BehaveResult rbol (remitente) { distWithEnemy = 200; enemyHe
alth = 100; Debug.log("al ralent durante un tiempo!"); return BehaveResult.xito; }
[ 176 ]
As que si ejecuta este comportamiento tree debera ver una lista de los mensajes de
registro en su consola que tiene un aspecto similar a la siguiente captura de p
antalla. Nuestro agente de AI es ahora el patrullaje, comprobando la distancia c
on el enemigo, atacando en consecuencia a nuestro comportamiento rbol y script:
La batalla entre robots y aliens
selector de prioridad
si est marcada, un selector de prioridad ser el agente de consulta a travs de su mto
do SelectTopPriority para la mxima prioridad de sus conexiones salientes. El sele
ctor de prioridad se marque la conexin correspondiente a la ID de ndice devuelta y
su valor de retorno se pasa. Si est marcada la conexin vuelve corriendo, entonces
el selector de prioridad no va a requerir en la prxima prioridad de garrapata. S
i una consulta devuelve la prioridad prioridad desconocido o un identificador ID
fuera de la consulta, el selector de prioridad devolver el fracaso.
[ 177 ]

As que vamos a crear un rbol como se muestra en el siguiente grfico con un selector
de prioridad y tres acciones, comer, dormir y jugar.
P l e a a t y P P r i o r i o s lo l r e y e s p p r i o r,
comer y dormir jugar
Selector de prioridad
es importante tener en cuenta que los pedidos de conexiones de salida son import
antes, as como sus valores de ndice se utilizar para hacer referencia a la secuenci
a de comandos. As, en este ejemplo, el ndice de conexin sera de 0 accin de comer, dor
mir, sera 1, y jugar sera 2. Y nuestro
mtodo SelectTopPrioirty se implementa de la siguiente manera:
private bool isHungry = true; privados bool isSleepy = true;
public int SelectTopPriority (rbol, params Sender ID int[]) { if (isHungry) { isH
ungry = false; isSleepy = true; retorno IDs[0]; //comer } else if (isSleepy) { i
sSleepy = false; retorno IDs[1]; //sleep } else { isHungry = true; retorno IDs[2
]; //play } }
[ 178 ]

damos prioridad a la accin isHungry comer si es verdadero y la accin del sueo si is


Sleepy es true. De lo contrario podemos elegir la accin del juego. A diferencia d
e las secuencias y selectores, selectores de prioridad no necesita pasar a travs
de la orden, y en su lugar nos puede devolver de inmediato una accin pertinente e
n funcin de las condiciones.
Qu ocurre si necesita varios selectores de prioridad en un rbol?
Una bsqueda rpida en Internet conduce a una respuesta de AngryAnt en Github Bahave
la lista de asuntos que se sugiere utilizar un selector variable de contexto pa
ra identificar que el selector se llama en el mtodo SelectTopPriority.
Puede ind esta y otras soluciones en https://github.com/AngryAnt/Behave-release/
issues/.
Paralelamente
el nodo paralelo garrapatas todos sus hijos cada vez que est marcada, de izquierd
a a derecha.
Hay dos opciones importantes para el nodo paralelo llamado el nio terminacin y ter
minacin de componentes. El nio terminar parmetro determina cmo el retorno del nio se
manejan valores como sigue:
Si se ajusta a un nio SuccessOrFailure salida est marcada como lo ha hecho siempre
que el nio devuelve SUCCESS o FAILURE
Si se ajusta al xito, ese nio slo obtiene el sello de hecho si devuelve
SUCCESS. Un retorno de fallo provocar en el componente paralelo regresar una
falla despus de haber marcado todos los nios
El fracaso configuracin funciona de la misma manera. El nio slo obtiene el sello de
hecho Si devuelve FAILURE
el componente finalizacin parmetro determina cundo el paralelo nodo devuelve un
xito basado en el nodo hijo hecho sello como sigue:
Si se establece en 1, el componente paralelo devolver el xito al final de la prime
ra graduacin de salida, donde un nio ha sido marcado como hecho
Si es para todos, el componente paralelo continuar ejecutndose hasta que todos los
nios hayan sido marcados como hecho
hasta el paralelo nodo puede devolver tanto el xito o el fracaso, cada marca de r
esultar en marcha
[ 179 ]

sera ms fcil de entender si observamos a travs de un ejemplo. As, vamos a configurar


un rbol con una secuencia en el nodo raz, un nodo con dos acciones paralelas, y ot
ra accin conectado al nodo de secuencia. Debe tener un aspecto similar a la sigui
ente captura de pantalla:
nodo paralelo
que vamos a configurar el componente variable de finalizacin en el nodo paralelo
a todos y el
nio la finalizacin con xito variable. Por lo tanto, eso significa que si todas las
acciones, y CheckEmail ListenMusic, devuelva el xito, sern marcados como hecho y e
l nodo paralelo devolver el xito. De lo contrario, volveremos el fracaso, y por lo
tanto la secuencia primaria nodo falla devolver tambin desde ese punto de vista,
lo que se traduce en la accin laboral, que nunca se llama.
Por lo tanto, volvamos a ejecutar la accin controladores para CheckEmail y Listen
Music. Volveremos el fracaso de la accin ListenMusic como se indica en el siguien
te cdigo y ver qu sucede:
pblico BehaveResult TickCheckEmailAction rbol (remitente) { Debug.log("La comproba
cin de correo electrnico"); return BehaveResult.xito; }
pblico TickListenMusicAction BehaveResult rbol (remitente) { Debug.log("mientras e
scucha msica!"); return BehaveResult.Fallo; }
[ 180 ]

observar que la accin nunca fue llamado. A continuacin, cambie el cdigo de accin List
enMusic para devolver el xito. Ahora todas las acciones bajo el nodo paralelo vol
ver
xito, as tambin podrs devolver el xito y la secuencia continuar la accin laboral.
Referencia
cuando cree otro comportamiento rbol en tu coleccin, ese rbol estar disponible en ot
ros rboles como referencia. Cuando las referencias estn marcadas, el rbol estableci
do en el parmetro de referencia ser la referencia marcada y devolver el resultado d
e ese rbol.
Las referencias son una buena manera de organizar diversos comportamientos difer
entes rboles en su proyecto.
NewCo
nodo Referencia
Los robots Versus Aliens proyecto
Este captulo viene con un proyecto de ejemplo llamado robots Versus Aliens que de
muestra el uso de comportarse comportamiento rboles en un prototipo de juego real
. Abrir el proyecto en Unity3D y recorreremos briely. El juego de demostracin y l
os agentes' AI son bastante simples. Esta es la forma en que la escena est config
urado, como se muestra en la siguiente captura de pantalla:
Jerarqua de escena
[ 181 ]

hay dos agentes de IA en este juego, el robot y el extranjero. Al comienzo del j


uego, unidades de cada lado se regenerar y cada una de ellas se marcha hacia la b
ase del enemigo. La base aliengena es similar a la siguiente captura de pantalla:
base aliengena
y la base del robot es similar a la siguiente captura de pantalla:
base del robot,
una vez que estn en una cierta distancia van a empezar a atacar, y una vez del ot
ro lado ha muerto va a avanzar de nuevo hasta que lleguen a la base. Una vez que
llegan a la base, que le acaba de atacar la base. Haga clic en AgentBehaveLibra
ry en el panel Proyecto y haga clic en Editar en el inspector de propiedades de
la biblioteca. Tenemos una coleccin y un rbol llamado AgentAI, tal como se muestra
en la siguiente captura de pantalla:
[ 182 ]

se comportan de
este navegador es cmo su comportamiento AI tree est estructurado, como se muestra
en la siguiente captura de pantalla:
robot aliengena rbol versus comportamiento
[ 183 ]

Hay tres principales scripts en este proyecto, para el extranjero AlienControlle


r AI,
RobotController para el robot AI y la base AgentAI clase, la cual es heredada po
r tanto de las clases del controlador. Puede ejecutar a travs del proyecto y veri
ficar los estados de accin utilizando el depurador se comportan. No vamos a enume
rar y recorrer todo el cdigo aqu desde todos los scripts estn muy bien comentados,
y usted debera ser capaz de entender leyendo usted mismo.
Robots Versus Aliens
Resumen
Este captulo presenta el comportamiento de los rboles en general y utiliza el sist
ema se comportan para aplicar tal comportamiento rboles en Unity3D. Hay seis comp
onentes bsicos que puede utilizar en comportarse comportamiento tree; accin, decor
ador, paralelo, Selector, selector de prioridad y secuencia. Cada uno tiene su p
ropio propsito y nos briely cubiertas cada una de ellas con sus respectivas muest
ras. Por ltimo, aqu hay algunas cosas que debe recordar al utilizar comportarse.
Usted tiene que reconstruir la biblioteca cada vez que realice cambios en los rbo
les de forma que los cambios son tambin relected biblioteca en cdigo compilado. Si
el rbol no est recibiendo ninguna garrapatas, debe comprobar la frecuencia de su r
bol y asegrese de que no est ajustado a cero.
Necesitas asegurarte de que ests instanciar el tipo de rbol correcto que desea uti
lizar en su declaracin InstantiateTree. Este captulo debera ser suficiente para emp
ezar con el comportamiento de los rboles en su juego. En el prximo captulo, vamos a
tirar de lo que hemos aprendido en la construccin de un proyecto inal.
[ 184 ]

Juntando Todo
a lo largo de los nueve captulos anteriores, analizamos diversas tcnicas de inteli
gencia artificial y construido algunas sencillas aplicaciones de demostracin util
izando Unity3D. Este es el ltimo captulo de nuestro libro y vamos a aplicar alguna
s de estas tcnicas en un juego mejor ejemplo. Las tcnicas que usaremos en este capt
ulo incluyen pathinding, inite-mquinas de estado (FSMs) y comportamiento de bloqu
eo junto con algunas otras caractersticas de juego genrico, como la creacin de clas
es para armas y Ammos. A diferencia de los otros captulos, ste debera ser un poco ms
divertida. Primero, vamos a crear el coche. A continuacin, le daremos algunos AI
. Despus de eso vamos a outit nuestros vehculos con armas para la batalla. Empecem
os por el principio.
En este captulo, vamos a ser la construccin de un simple juego de combate vehicula
r inspirado por la popular saga de Twisted Metal en la plataforma PlayStation. P
or lo tanto, naturalmente, habr automviles y gunights y explosiones, pero ser mucho
ms sencillo que en nuestra versin. Este proyecto despus de todo todava es una demo,
y no estaremos construyendo un juego completo con sistemas de puntuacin, potenci
adores, pantallas de men, y la personalizacin de cosas. As, en una versin reducida d
e nuestro juego de combate vehicular, implementaremos un automvil controlado por
jugador y una clase de AI para coches adversarios. El jugador coche estar equipad
o con dos armas diferentes; una pistola normal con balas y un lanzamisiles que r
astrear si se dirigen a un enemigo de coche.

Configurar las escenas


as que empecemos con cmo nuestra escena ha sido estructurado.
Los objetos de la jerarqua
tenemos cuatro coches AI agrupados bajo la entidad AICars y un jugador de automvi
l controlado por entidad.
La realista modelo de coche, coche y comportamientos de movimiento de la cmara se
basaron en los scripts de Unity3D coche proyecto del tutorial. Puedes descargar
y aprender ms sobre l en Http://u3d.as/ content/unidad-tecnologas/auto-tutorial/.
[ 186 ]

Tambin hemos establecido puntos de referencia para los coches AI para patrullar y
un grupo controlador de bloqueo con los objetos como entidades secundarias bajo
l. Si desea crear un ambiente ms realista puede agregar otros tipos de luz, y con
struir un mapa de luz para generar sombras para un modo de lnea. Pero en esta dem
ostracin, utilizaremos una luz direccional simplemente para iluminar la escena. E
l juego de jugador recticle objeto se usa para hacer referencia a la posicin de d
estino sealado por el ratn. Adems de bloque esttico obstculos tambin tenemos obstculos
dinmicos que son afectados por la fsica y puede ser destruido por nuestras armas.
Esto es lo que nuestra pequea escena parece:
Cmo ve la escena desde arriba
[ 187 ]
etiquetas y capas de
secuencias de comandos antes de comenzar hay un importante paso para configurar,
que es conigure etiquetas utilizadas en nuestro juego. Las etiquetas y las capa
s se pueden configurar a travs de Editar | Configuracin del proyecto | Etiquetas.
Podemos usar nombres de objetos o etiquetas al referenciar e identificar objetos
del juego en la escena desde un script utilizando mtodos como GameObject.
FindWithTag(). Las capas son usadas principalmente para establecer una mscara de
sacrificio para cmaras para procesar slo las partes seleccionadas de la escena, y
por las luces para iluminar slo las partes de la escena. En este proyecto estamos
usando capas para slo detectar colisiones entre speciic capas. Veremos ms adelant
e, cuando los utilizamos en scripting. Por ahora, simplemente tomar nota de que
las etiquetas y las capas estn configurados como se muestra en la siguiente captu
ra de pantalla:
etiquetas y capas utilizadas en nuestro juego
[ 188 ]

Los vehculos
mencionados anteriormente el modelo de automvil y scripts de comportamiento se ba
san en el Unity3D coche tutorial. Algunas de las secuencias de comandos escritas
en JavaScript fueron convertidos en C# para hacerlos coherentes.
Nuestro coche equipado con armas
hemos aadido tres componentes adicionales a nuestra base modelo de automvil. Son l
anzadores de misiles en cada lado de la carrocera del automvil y un modelo de pist
ola normal con una torreta giratoria en la parte superior. Asimismo, tomamos not
a de que el jugador coche utiliza la etiqueta de Jugador y enemigo coches utilic
e la etiqueta que nos deined AICar anteriormente.
Las modificaciones aadidas a nuestro coche
[ 189 ]

Reproductor
Reproductor controlador coche coche tiene unos scripts diferentes conectados a l.
Bsicamente Car.cs y
PlayerCarController.cs cuidar el movimiento del carro de manera realista. Desde
coche realista fsica es un gran tema, y como usted tambin puede aprender de la Uni
ty3D coche tutorial, estaremos mirando ms hacia nuestro proyecto speciic secuenci
as de comandos y controladores en este captulo. La siguiente es nuestra clase Pla
yerWeaponController que controla el apuntar y disparar de nuestras dos armas dif
erentes:
utilizando UnityEngine; using System.Collections;
public class PlayerWeaponController : pistola WeaponGun MonoBehavior{ pblica; pbli
ca WeaponMissile[]; //misiles a izquierda y derecha de la torreta de transformac
in pblica pod misiles;
//El objeto Recticle, el cursor grfico transformar recticle privado;
// Utilice esta inicializacin void Inicio () { if (!recticle) = GameObject rectic
le.Find("Recticle_player.transform"); }
// se llama a Update una vez por fotograma vaco de actualizacin () { //disparar lse
r de la torreta si (Input.GetMouseButtonDown(0)) { gun.Shoot(); } else if (Input
.GetMouseButtonUp(0)) { gun.StopShoot(); }
//dispara desde la torreta de misiles si (Input.GetMouseButtonDown(1)) {[1].misi
les disparar(); } else if (Input.GetMouseButtonUp(1)) {[1].misiles StopShoot();
}
[ 190 ]

//Girar la torreta //apuntando con el ratn //Generar un Plano que intersecta la t


ransformacin //posicin con arriba de lo normal.
Avin playerPlane = nuevo avin(vector3.up, transform.posicin);
// generar un rayo desde la posicin del cursor Ray RayCast = Cmara.main.ScreenPoin
tToRay(Input.mousePosition);
// Determinar el punto donde el cursor ray cruza el //avin.
float HitDist = 0;
Si (playerPlane.Raycast(RayCast, HitDist)) { // Obtener el punto a lo largo del
rayo que golpea el //distancia calculada.
Vector3.GetPoint RayCast targetPoint =(HitDist);
//Establecer la posicin de la Recticle ser el mismo que el //posicin del ratn en el
plano creado
recticle.posicin = targetPoint; Torreta.LookAt(recticle.position); } } }
comenzamos con teniendo en entidades de referencia para armas de proyectiles y l
a torreta giratoria.
Todava tenemos que crear la clase WeaponMissle WeaponGun o la clase, pero lo hare
mos, ms adelante en este captulo. La recticle separados, a objeto de juego vaco en
nuestra escena. En el mtodo start, intentamos ind ese objeto en la escena, y alma
cene una referencia en nuestro local recticle. A continuacin, en nuestro mtodo Upd
ate, utilizamos el evento click del botn izquierdo del ratn para disparar disparar
balas normales y con el botn derecho del ratn para disparar misiles. A continuacin
, podemos elegir la posicin actual del puntero del mouse (ratn) en el espacio 2D y
convertirlo en un espacio 3D por raycasting. Esto ha sido explicado en el Captul
o 2, mquinas de estado finito, en la seccin titulada controlando el tanque. A cont
inuacin, el objeto de la torreta conectada al coche se gira a mirar en esa direcc
in, y tambin la posicin recticle est actualizado. Esta posicin de la imagen recticle
se actualiza en tiempo real.
[ 191 ]

AI Car Controller
AdvancedFSM aplicaremos el marco que hemos creado en el Captulo 2, mquinas de esta
do finito, para implementar el enemigo AI del coche. La clase AICarController Ad
vancedFSM se extiende desde la clase y definir el marco de ups FSM.
utilizando UnityEngine; using System.Collections;
public class AICarController : AdvancedFSM { protected override void Initialize(
) { //Start haciendo la mquina de estado finito ConstructFSM();
//Obtener el objetivo enemigo(Jugador) GameObject objPlayer = GameObject.FindGam
eObjectWithTag("Player"); = objPlayer playerTransform.transform;
si (!playerTransform) print("Jugador no existe.. Por favor, aada una con " + "eti
queta denominada "Player"); }
tenemos que asegurarnos de que hay un objeto Player con la etiqueta de jugador e
n la escena. Si la encuentra, nosotros guardaremos esta referencia de objeto en
la variable playerTransform. A continuacin, establecemos nuestras transiciones y
estados en el mtodo ConstructFSM.
//Construir la mquina de estado finito para el coche AI comportamiento private vo
id ConstructFSM() { //Obtener la lista de puntos.FindGameObjectsWithTag GameObje
ct pointList =("WandarPoints"); transformar[] waypoints = nueva transformacin[poi
ntList.Length]; int i = 0; (foreach GameObject obj en pointList) { waypoints[i]
= obj.transform; i++; }
= nueva patrulla PatrolState PatrolState(waypoints); inspeccin.AddTransition(Tran
sicin.SawPlayer, FSMStateID.persiguiendo); inspeccin.AddTransition(Transicin.NoHeal
th, FSMStateID.muertos);
[ 192 ]

ChaseState chase = new ChaseState(waypoints); chase.AddTransition(Transicin.LostP


layer, FSMStateID.patrullando); chase.AddTransition(Transicin.ReachPlayer, FSMSta
teID.atacar); chase.AddTransition(Transicin.NoHealth, FSMStateID.muertos);
ataque AttackState = new AttackState(waypoints); el ataque.AddTransition(Transic
in.LostPlayer, FSMStateID.patrullando); el ataque.AddTransition(Transicin.SawPlaye
r, FSMStateID.persiguiendo); el ataque.AddTransition(Transicin.NoHealth, FSMState
ID.muertos);
nueva DeadState DeadState muerto =(); dead.AddTransition(Transicin.NoHealth, FSMS
tateID.muertos);
AddFSMState(patrulla); AddFSMState(chase); AddFSMState(ataque); AddFSMState(muer
tos); }
establecemos un par de puntos en nuestra escena para usar como puntos de referen
cia para nuestros coches AI para navegar en la escena.
Nuestra escena necesita un montn de puntos
[ 193 ]

Estos waypoints utilizar la etiqueta WandarPoints. As que la primera cosa que ten
emos que hacer, mientras construyendo nuestro FSM, es ind todos aquellos puntos
etiquetados como WandarPoints y pasarlos a nuestros miembros de AI, para que sea
n conscientes de su entorno.
Patrol puntos etiquetados como WandarPoints
despus de eso, nos crean estados y desencadenadores de transicin y aadiendo en nues
tro marco de Micronesia.
Las mquinas de estado finito (FSMs)
necesitamos establecer un bucle de actualizacin que se llame a los mtodos de razon
ar y actuar desde nuestras diversas clases de estado. Nos centraremos en la apli
cacin de estos estados en un tiempo.
protected override void CarFixedUpdate() { CurrentState.Razn(playerTransform, tra
nsform); CurrentState.Act(playerTransform, transform); }
Ya estamos separados de los diferentes estados de nuestro coche AI en diferentes
clases, nuestro mtodo de actualizacin es mucho ms sencillo. Slo necesitamos llamar
a los mtodos de razonar y actuar sobre el estado actual de la IA. Para representa
r el FSM nuestro modelo de AI coches en un diagrama de transicin de estados, sera
algo como esto.
Ataque
sin llegar a jugador pierde la salud Reproductor Reproductor
Reproductor sierra sierra Patrol Chase perdi player
no hay salud sin salud
muertos
para el FSM AI enemigo coche
[ 194 ]
y la ltima parte es tomando el dao basado en colisin con balas o misiles.
Una vez que la salud llegue a menos de o igual a cero, vamos a jugar un bonito e
fecto de explosin fsica, destruir el objeto, y originalmente quitarlo de la escena
.
//Hit con bala o misil void OnCollisionEnter(Colisin colisin) { if (bDead) volver;
si (colisin.gameObject.tag == "Bullet") { print("AICar Hit con bala"); salud -= 3
0; } else if (colisin.gameObject.tag == "misil") { print("AICar Hit con misil");
salud -= 50; }
Si (salud &lt;= 0) { bDead = true; explode(); destruir(gameObject, 4.0F); } }
estado patrulla
cada estado en nuestro FSM tiene dos mtodos principales, la razn y la ley. Bsicamen
te, la razn mtodo comprueba la condicin y toma cuidado de transicin a otros estados.
En nuestro estado, patrulla la razn mtodo comprueba la distancia entre el jugador
y la actual posicin de coche AI. Si es lo suficientemente cerca, asignar la trans
icin a SawPlayer. Ya hemos establecido la correlacin entre estados y transiciones
para cada uno de nuestros objetos car AI.
public void override razn(Transformar player, transformar npc) { if (Vector3.Dist
ancia(npc.posicin, player.posicin) &lt;= 100,0 F) { Debug.log("Cambiar a estado Ch
ase"); CPN.GetComponent <AICarController>().SetTransition( Transicin.SawPlayer);
CPN.GetComponent <AICarController>().acelerador = 0.0f; CPN.GetComponent <AICarC
ontroller>().DoHandbrake(); } }
[ 195 ]

as, ms adelante en nuestra clase AdvancedFSM, esta nueva transicin se utiliza para
recuperar el estado actual correctamente. El siguiente es el mtodo de la Advanced
FSM PerformTransition clase que administra esta transicin de estado.
public void PerformTransition(Transicin trans) { // comprobar si el currentState
la transicin ha pasado como //argumento FSMStateID id = currentState.GetOutputSta
te(trans); if (id == FSMStateID.None) { Debug.LogError("FSM ERROR: Estado actual
no tiene un signo " + "Estado de destino para esta transicin"); return; }
// actualizacin del currentStateID currentStateID y currentState = id; (foreach e
n estado FSMState fsmStates) { if (estado.ID == currentStateID) { currentState =
estado; break; } } }
y la Ley Mtodo de nuestra Patrulla miembros ind el siguiente punto de referencia,
si el coche AI ya est cerca del punto de destino actual, y se encargar de la actu
alizacin de la direccin y la velocidad en consecuencia.
public void override Act(Transform Player, transformar npc) { //buscar otro punt
o de patrulla aleatoria si el punto actual es //alcanzado si (Vector3.Distancia(
npc.posicin, destPos) &lt;= 5.0f) { FindNextPoint(); curPathIndex = 0; //Freno pr
imero antes de pasar al siguiente punto npc.GetComponent <AICarController>().DoH
andbrake(); } }
[ 196 ]

La razn de Estado Chase mtodo comprueba y transiciones a ReachPlayer, si la distan


cia entre el jugador y el AI coche est lo suficientemente cerca. De lo contrario,
necesitar actualizar la transicin a
LostPlayer. As la transicin ReachPlayer actualizar el estado AI para el ataque de e
stado mientras LostPlayer har que la AI coche patrulla volver al estado.
//verificar la nueva razn para cambiar de estado public void override razn(Transfo
rmar player, transformar npc) { // Establecer la posicin de destino como el jugad
or posicin = destPos player.posicin;
//controlar la distancia con el jugador depsito //cuando la distancia est cerca, l
a transicin al ataque de flotacin del estado dist = Vector3.Distancia(npc.posicin,
destPos); if (dist &lt;= 60.0f) { Debug.log("Cambiar a estado de ataque"); CPN.G
etComponent <AICarController>().SetTransition( Transicin.ReachPlayer); }
//volver a patrullar es demasiado lejos si (dist &gt;= 110.0f) { Debug.log("Camb
iar a estado de patrulla"); CPN.GetComponent <AICarController>().SetTransition(
Transicin.LostPlayer); } }
El mtodo Ley del estado Chase es corto pero requiere algunos antecedentes sobre lg
ebra lineal y trigonometra.
//medidas adoptadas en el estado actual de anulacin pblica Act(void reproductor de
transformacin, transformar npc) { //Girar al punto de destino destPos = player.p
osicin;
CNP.GetComponent <AICarController>().acelerador = 1.0f;
Vector3.InverseTransformPoint RelativeWaypointPosition = npc(nuevo Vector3(destP
os.x.y.La posicin de NPC, destPos.z));
CPN.GetComponent <AICarController>().Direccin = RelativeWaypointPosition.x / Rela
tiveWaypointPosition.magnitud; }
[ 197 ]

Unity3D tiene un mtodo llamado InverseTransformPoint que traduce una posicin del m
undo espacio al espacio local. Actualmente el jugador se encuentra en el espacio
mundial. As, podemos utilizar este mtodo para ind la posicin relativa del coche re
productor de destino desde la posicin de AI alquiler de transformacin. RelativeWay
pointPosition sostiene el nuevo vector (x, y, z), que es tambin el vector de dire
ccin al jugador coche del coche AI.
Encontrar el vector para el jugador de coche
una vez que tengamos este vector podemos determinar por qu grado necesitamos para
girar, en su caso, hacia la direccin de coche jugador dividiendo la posicin horiz
ontal por la magnitud vectorial o la distancia. A partir de ah, aplicamos este va
lor angular para girar las ruedas hacia el jugador coche.
Estado de ataque
cuando el jugador est suficientemente cerca del AI coche, podemos alcanzar el est
ado de ataque. Vamos a girar la pistola hacia el jugador coche y empezar a dispa
rar coroutine.
public void override Act(reproductor de transformacin, transformar npc) { // Esta
blecer la posicin de destino como el jugador posicin = destPos player.posicin + nue
vo Vector3(0.0F, 1.0F, 0.0F);
Transformacin = arma.Torreta torreta; Quaternion turretRotation = Quaternion.Look
Rotation( destPos -.La posicin de la torreta);
[ 198 ]

.la rotacin de la torreta = Quaternion.Slerp(.la rotacin de la torreta, turretRota


tion, tiempo.deltaTime * curRotSpeed);
//Shoot no debera llamar cada fotograma si (!bStartShooting) { //Shoot bullet/mis
iles hacia el jugador ShootShells(); bStartShooting = true; } }
en nuestra razn mtodo, debemos comprobar la distancia con el jugador y establecer
la transicin de regreso a LostPlayer o SawPlayer. Estas transiciones actualizar el
estado actual para patrullar estado o estado chase.
public void override razn(Transformar player, transformar npc) { // comprobar la
distancia con el coche jugador float dist = Vector3.Distancia(npc.La posicin,repr
oductor.posicin); if (dist &gt;= 50,0f &amp;&amp; dist &lt; 100,0 F) { Debug.log(
"Cambiar a estado Chase"); CPN.GetComponent <AICarController>().SetTransition( T
ransicin.SawPlayer); StopShooting(); }
//transicin para patrullar el depsito est demasiado lejos else if (dist &gt;= 100,0
F) { Debug.log("Cambiar a estado de patrulla"); CPN.GetComponent <AICarControll
er>().SetTransition( Transicin.LostPlayer); StopShooting(); } }
armas
nuestro coche controlado por el jugador tiene dos armas; un lanzamisiles y una p
istola normal, mientras que los coches AI slo tienen una pistola normal. Echemos
un vistazo a ellos para ver cmo se est aplicando. No hay muchas tcnicas de AI aqu au
nque.
[ 199 ]

La pistola WeaponGun clase simplemente engendra a disparar balas llamando a su mt


odo.
utilizando UnityEngine; using System.Collections;
public class WeaponGun : MonoBehavior { public GameObject bala; pblico GunGraphic
s GameObject[]; flotacin pblica ratePerSecond; privados bool bShoot;
// Utilice esta inicializacin void Start() { bShoot = false; }
public void disparar() { bShoot = true;
(foreach GameObject obj en GunGraphics) { obj.animation.CrossFade("GunShooting",
0.5F); }
StartCoroutine("ShootBullets"); }
al disparar balas no queremos instanciar demasiadas vietas a la vez a causa de un
a alta calificacin de fotogramas por segundo. Por el contrario, deseamos limitar
la tasa de disparo a un usuario speciic deined valor. Queremos esperar una durac
in speciic antes del desove otra vieta. Podemos hacer esto mediante coroutines en
Unity3D.
public void StopShoot() { //detener la animacin de disparo si (bShoot) { bShoot =
false;
(foreach GameObject obj en GunGraphics) { obj.animation.stop("GunShooting"); } }
StopCoroutine("ShootBullets"); }
[ 200 ]

Como se explica en el Unity3D, una referencia coroutine es una funcin que puede s
uspender su ejecucin (rendimiento), hasta que los dados YieldInstruction inishes.
Podemos iniciar y detener coroutines utilizando el StopCoroutine StartCoroutine
y mtodos. El siguiente es nuestro mtodo, ShootBullets coroutine. En este mtodo, de
bemos esperar un cierto nmero de milisegundos basndose en el valor ratePerSecond s
peciied.
privada IEnumerator ShootBullets() { SpawnBullet(); nueva WaitForSeconds yield r
eturn(1.0f / ratePerSecond); StartCoroutine("ShootBullets"); }
Este mtodo coroutine slo llama a nuestro mtodo SpawnBullet que crea una nueva vieta
de prefabricados en una posicin aleatoria y rotacin a lo largo de la pistola de po
sicin.
private void SpawnBullet() { int rndSpawnPoint = Random.Range(0, GunGraphics.Len
gth); Vector3 =[rndSpawnPoint SpawnPos GunGraphics].transform.posicin; Quaternion
SpawnRot =[rndSpawnPoint GunGraphics].transform.rotacin;
//Crear una nueva vieta GameObject objBullet = (GameObject)instanciar(Vieta SpawnP
os, SpawnRot); } }
Bullet
la bala objeto est configurado como un llamado PlayerLaser prefabricado. En el ca
ptulo de activos, puede ind bajo Activos | Recursos | | Prefabs balas.
Ubicacin de todas nuestras armas
[ 201 ]

La clase de comportamiento de vieta se agrega a este lser prefabricado de vieta. Ta


mbin tiene un cuerpo rgido y el recuadro de hadrones componentes, por lo que podem
os detectar colisiones con otros objetos. Necesitamos tambin un efecto de partcula
s para ser jugado cuando choca contra algo.
Configuracin y apariencia de nuestro bullet
y aqu est nuestra clase de bala. La primera cosa que hacemos en nuestro mtodo Start
es destruir este bullet juego objeto automticamente despus de dos segundos.
utilizando UnityEngine; using System.Collections;
public class Bullet : partculas GameObject MonoBehavior { public_Hit; flotacin pbli
ca velocidad = 100,0 f;
// Usar este para inicializacin void Start() { Destroy(gameObject, 2.0F); }
[ 202 ]

y en el mtodo Update, Simplemente trasladamos avanzan en la direccin Z positiva pa


ra avanzar con una velocidad deined.
// se llama a Update una vez por fotograma vaco actualizacin () { transform.transl
ate(nuevo Vector3(0, 0, * Tiempo de velocidad.deltaTime)); }
void OnCollisionEnter(Colisin colisin) { Vector3 contactPoint = colisin.contactos[0
].El punto;
instanciar(Partcula_Hit, contactPoint, Quaternion.identidad); destruir(gameObject
); } }
El mtodo se llama OnCollisionEnter cuando este juego objeto colisiona con algo. A
cabamos de reproducir el efecto de partculas de vieta adjunta y destruir el objeto
de vieta. El otro juego objeto siendo golpeada por una bala manejar la daina toman
do y conmutacin de estado de las tareas.
Lanzador
El lanzamisiles arma es tambin similar a la pistola armas de clase. Genera los mi
siles, y utiliza coroutines a esperar unos milisegundos entre cada instanciacin d
e misiles. La nica diferencia con la pistola arma es misiles tienen un modo de bl
oquear y perseguir la meta si el jugador apunta y dispara correctamente en un en
emigo AI coche.
utilizando UnityEngine; using System.Collections;
public class WeaponMissile: misiles GameObject MonoBehavior { pblica; pblica trans
formar SpawnPoint; privados bool bShoot, bHasTarget; Transformacin privado destin
o;
// Usar este para inicializacin void Start() { bShoot = false; bHasTarget = false
; }
[ 203 ]

Entonces, inicializamos nuestras propiedades en el mtodo Start. Y en el rodaje de


mtodo que utilizamos raycasting para probar si hay un coche de AI en la posicin a
ctual del ratn.
public void disparar() { // comprobar si existen o no destino Ray ray = Cmara.mai
n.ScreenPointToRay(Input.mousePosition); RaycastHit hitInfo;
//RayCast slo a AI Coche que es la capa nmero 9 int layerMask = 1 &lt;&lt; 9;
Si (Fsica.Raycast(ray, hitInfo, 1000.0f, layerMask) { bHasTarget = true; target =
hitInfo.transform; } else { bHasTarget = false; }
bShoot = true; StartCoroutine("ShootMissiles"); }
El mtodo Raycast mscara de capa del parmetro determina qu capas a prueba contra el r
ayo generado. Capa de coche AI que hemos creado en la capa nmero 9 anteriormente.
A poco desplazando el nmero uno, (...0000000001) en binario, nueve lugares hacia
la izquierda, se convierte en (...001000000000) en binario. El resultado es que
todas las capas excepto la capa 9 ser desatendido mientras realiza raycasting. S
i ese rayo impacta con un coche, entonces AI estableceremos bHasTarget en true y
se fij como objetivo la transformacin. Luego comenzamos la
ShootMissiles coroutine.
public void StopShoot() { //detener la animacin de disparo si (bShoot) { bShoot =
false; } StopCoroutine("ShootMissiles"); }
IEnumerator ShootMissiles privado() { SpawnMissile(); nueva WaitForSeconds yield
return( Random.Range(0.3F, 0.6F); StartCoroutine("ShootMissiles"); }
[ 204 ]

private void SpawnMissile() { // crear un nuevo misil GameObject objMissile = (G


ameObject)instanciar(Misil, SpawnPoint.posicin, SpawnPoint.rotacin);
objMissile.GetComponent <Missile>().Initialize(bHasTarget, destino); } }
finalmente en el mtodo SpawnMissile, creamos una instancia de un nuevo misil de p
refabricados en el arma de misiles. Entonces, obtenemos el script de misiles, y
decirle que si tenemos una meta y lo que es objetivo.
Nuestro WeaponMissile lanzador de misiles o armas de clase genera cada misil. Du
rante la inicializacin se comprueba si existe un objeto de destino para perseguir
y destruir a este misil.
utilizando UnityEngine; using System.Collections;
public class : MonoBehavior misiles { public_partculas GameObject golpeado; flota
cin pblica velocidad = 20.0f; privados de destino de transformacin;
public void Initialize(bool bHasTarget, transformar target = null) { if (bHasTar
get) { this.target = objetivo; destruir(gameObject, 4.0F); } else { Destroy(game
Object, 2.0F); } }
[ 205 ]

Si hay un objeto de destino, en nuestro mtodo Update, estamos constantemente va la


posicin objetivo y actualizar la direccin y los valores de rotacin de nuestro misi
l en consecuencia.
// se llama a Update una vez por marco void Update() { if (target != null) { //H
acer la posicin de destino hacia arriba un poco bit newTarPos Vector3 = target.po
sicin + nuevo Vector3(0.0F, 1.0F, 0.0F);
//gire hacia la meta de Vector3 = newTarPos tarDir - transform.posicin; Quaternio
n tarRot = Quaternion.LookRotation(tarDir); transform.rotacin=Quaternion.Slerp(tr
ansform.rotacin, tarRot, 3.0f * Tiempo.deltaTime); }
transform.translate(nuevo Vector3(0, 0, * Tiempo de velocidad.deltaTime)); }
Finalmente, al igual que en nuestra clase de bala, cuando el misil golpea algo q
ue acabamos de reproducir el efecto de partculas de explosin y destruir los misile
s objeto.
void OnCollisionEnter(Colisin colisin) { Vector3 contactPoint = colisin.contactos[0
].El punto;
instanciar(Partcula_Hit, contactPoint, Quaternion.identidad); destruir(gameObject
); } }
[ 206 ]

Esto producir un efecto fro del destino bloqueado misil lanzado desde el lado del
coche, como se muestra en la Captura de pantalla siguiente:
lanzando misiles contra nuestros enemigos
[ 207 ]

Resumen
En este captulo hemos aplicado algunas de las tcnicas de inteligencia artificial q
ue hemos aprendido anteriormente a nuestro sencillo juego de combate vehicular.
Seramos capaces de aplicar algunas tcnicas ms en un juego de mayor alcance, pero en
este breve captulo hemos reutilizado el FSM avanzado marco que hemos creado en e
l Captulo 2, mquinas de estado finito, as como waypoint y ruta tcnicas siguientes. T
ambin podramos utilizar nuestro sistema sensor, detectando el entorno para la AI c
oches. Pero para hacer el captulo ms simple podemos slo accedi a la posicin del jugad
or y comprobar la distancia entre los dos directamente. Los coches AI seguir y at
aque una vez el reproductor coche est cerca de ellos, incluso si no est en su lnea
de visin. As que esta es un rea que puede aplicar a fin de hacer el juego mejor. Es
te es el ltimo captulo de este libro, y esperamos que hayan aprendido algo nuevo e
n reas relacionadas con la inteligencia artiicial en juegos as como en Unity3D.
[ 208 ]

Un
algoritmo A* acerca de pruebas de 123, 124 141, 142 164, 165 accin AdvancedFSM cl
ase 196 clase AdvanceFSM AdvancedFSM marco 192 53 48, 49, 48, 49 Agent 115 184 c
lase AgentAI AgentController.cs ile 166 AI unos 5 juegos en 6 reas de investigacin
6 sistemas sensoriales 76 tcnicas 7 AI Car Controller 192, 194 entidad AICars 18
6 caracteres AI unos 81, 82 sentido de perspectiva de clase 83 pruebas de detecc
in 83-85 88 touch sense 86, 87 167 extranjeros proyecto AIUpdate mtodo versus Robo
ts proyecto regla de alineacin de 181-184 11 un algoritmo pathinding* 13-20 126 I
nteligencia Artiicial tipo ArrayList. Ver AI.cs 81 clase de aspecto aspecto.cs i
le 81 81
ndice
mtodo AssignNeighbor aspectName 131 clase AStar 123 132-134 132-134.mtodo FindPath
AStar 136 Estado de ataque 44, 198 bienes propiedad avoidanceRadius avoidanceFo
rce 92 92 mtodo AvoidObstacles 117-119
B
comportarse plugin depurador unos 160 171 pasos para descargar, instalar, 160, 1
61, 160, 161 pasos de resultados, explorar 173, 174 se comportan.Runtime namespa
ce comportamiento 166 rboles 23-25 68 BLAgentBehaveLib betResult guiText objeto.T
reeType variable 169 bullet clase 35, 36 Bullet objeto 201
C
CalculateNextMovementPoint() mtodo 98 mtodo mtodo CalculatePath CalculateObstacles
129 134, 135 C# FSM 29 marco chase estado 43, 197 checkBet() mtodo de cohesin 71 R
egla 11 mtodo CompareTo 125, 126 Componente variable de finalizacin 180 probabilid
ad condicional alrededor de 59 dados cargados 60, 61
97 clase de controlador. Mtodo coroutine 201 objeto juego Cube 38
D
45 estado muerto, 46 mtodo DebugDrawGrid decorador 132 169, 170 Defensa de los an
tiguos (DotA) 9 mtodo DetectAspect 85 algoritmo de Dijkstra 28 propiedad directio
n 114 Dynamic AI 64, 65
E
88 mensaje detectado enemigo tanque enemigo AI unos 39-41 ataque estado 44 chase
estado 43 muertos 45 estado estado de patrulla 42 eventos componente 8 Propieda
d Explosion 36
F
173 accin FadeIn FadeOut 174 accin mtodo mtodo FindPath FindNextPoint 42 133 mquinas
de estado finito. Ver FSM FixedUpdate() mtodo 68, 71 FlockController aproximadame
nte 101-104 cdigo de bloqueo 101 alrededor del 89 de la unidad de demostracin de l
a isla 89, 90 aplicacin followRadius followVelocity 99-101 92 92 FSM alrededor de
7, 29, 159, 185, 194, 195 RESUMEN FSM clase 38, 39 Estado de ataque 198
[ 210
chase estado 197, 198 componentes 8 tanque enemigo AI 39 Estado de patrulla 195,
196 9 aleatorio con probabilidad 62-64 FSM, eventos de componentes Componente 8
componente reglas 8 Estado 8 componente componente 8 transiciones de clase FSMS
tate 49
G
Game Developers Conference (GDC) 12.FindWithTag GameObject(), mtodo 188 GetColumn
mtodo mtodo GetGridIndex GetNeighbors 130 129 134 mtodo mtodo mtodo GetRow GetPoint
111 130 clase objeto GridManager GridManager 123-129 128 elemento objeto guiText
guiText 68 58
H
mtodo HeuristicEstimateCost 132 159 HFSM FSM jerrquica. Ver HFSM Redes jerrquica de
tareas. Ver HTNs HTNs 159
I
mtodo Initialize 83, 85 166 InstantiateTree InstantiateTree mtodo mtodo esttico 166
intervalTime 136 es el bucle lag 111
L
arma lanzadora clase 205 capas, 188 116 111
] la propiedad Longitud de

locomocin 25-27
m de
longitud de Manhattan 15 mapa estableciendo la propiedad pendiente mx. 144 150 10
sistema de mensajera variable minimumDistToAvoid 120 lanzamisiles 203 armas, 204
mousePosition 32
n objeto de
procesamiento del lenguaje Natural (PLN) 6 malla de navegacin Acerca de 20-22, 14
4 145, 146 para hornear 145 navmesh esttica de navegacin. Ver malla de navegacin Na
v agente acerca de malla 146, 147 destino, actualizando 148 Target.cs la clase 1
48, 149 147 149 matriz NavMeshAgent URL NavMeshLayers unos 151 152 152 Crear nue
va capa, aadiendo 153 near miss 73, 74 Clase de nodo 125 126 136 el objeto Nodo d
e los personajes no jugadores (PNJ) 7 NPCTankController clase 52, 53
o
129 propiedad obstacleList obstculos alrededor de 114 evitando 115-120 capa perso
nalizada, aadiendo 116 Off Enlaces de malla alrededor de 153, 154, 155 154 de gen
eracin manual desactivado 156
157 URL mtodo OnDrawGizmos 85, 111, 136 OnGUI() mtodo OnGUI OnGUI 60 117() mtodo 58
, 61, 64, 68, 86 mtodo OnTriggerEnter OnTriggerEnter EVENTO
PARALELO NODO 87 P 179, 180 PARS 69 ParticleExplosion 36 sobre la ruta 108, 110
aadiendo 108 seguidor script 111-114 110, 111 Propiedad pathArray 136 Ruta.cs scr
ipt 108 Estado de Patrulla 42, 195 PatrolState clase 50, 51 Paytable y tiras del
molinete. Ver mtodo PerformTransition PARS 52, 196 Perspectiva.cs ile 83 sentido
de perspectiva fsica 83, 85.mtodo Raycast 120 player car controller 190, 191 30 d
epsito jugador clase PlayerTankController unos 30 bullet clase 35, 36, 32 propied
ades de disparo de bala 31, 32 depsito, controla 32, 34 PlayerTankController.cs i
le cdigo 31 PlayerTank.cs ile 79 juego PlayerTank objeto script PlayerTank player
Transform 30 79 192 colegios 10 PriorityQueue variable clase 123, 124, 126, 127
PriorityQueue.cs 126 clase PRNG probabilidad aproximadamente 56 56
[ 211 ]

probabilidad condicional 59 58 deining probabilidad ponderada 69-72 con el FSM 6


2, 63 nmero pseudoaleatorio generador. Tire de la palanca hacia el botn Ver PRNG 6
8
R
propiedad radio 110 URL de lluvia 76 aleatorio sobre 55, 56 clase 56 juego de da
dos 57, 58 randomFreq 91 la generacin de nmeros aleatorios. Ver RNG randomPush val
or aleatorio 91.El valor de la propiedad Mtodo rango 56 57 Mtodo Raycast 85, 119,
204, estrategia en tiempo real (RTS) juego de 9 Jugador recticle objeto de refer
encia 187 y 191 181 167 Mtodo Reset volver al reproductor. Consulte RTP Rigidbody
componentes 30, 46 RNG 56 Robots proyecto Versus Aliens proyecto RTP 181-184 69
componente reglas
configurando la escena 8 S 76, 77, 137-139, 186, 187 script interactuar con 166,
168 propiedad de semillas 56 selectores alrededor de 175-177 177-179 mtodo Selec
tTopPriority selector de prioridad 168, 177 sentido clase 83 Sentido.cs ile 83
[ 212
sensores 75 Aplicacin del sistema sensor de separacin de 10, 76 Regla 11 secuencia
172 mtodo SetTransition 51 mtodo de disparar 200 ShouldDoMyAction decorador 170 s
_Instance variable esttica 128 pendiente escena, edificio con 149-151 slot machin
e demo 65 mquina de ranura aleatoria de 65, 68, 69 El mtodo Sort 127 201 SpawnMiss
ile SpawnBullet mtodo mtodo mtodo StartCoroutine 205 93, 201 31 Funcin Inicio mtodo S
tart 83, 112, 136 mtodo start() de la clase 70 50 componente estatal 8 matriz sta
tesPoll 64 aproximadamente 12 capas de direccin 12, 13 steer(), mtodo 100, 101 mtod
o mtodo StopCoroutine Direccin 114 201
T
188 etiquetas de control de depsito 32-34 Target.cs la clase 148 TargetMovement u
nos 104 ile 104, 105 objetos de destino 78, 80 targetTransform 80 variable varia
ble de destino 102 Taxi geometra. Ver Manhattan longitud TestCode clase 135, 136
throwLoadedDice() mtodo 60 mtodo de graduacin 167, 168
]

toOriginRange toOriginForce 92 92 Touch.cs ile 86 touch sense 86, 87 transicione


s componente 8 mtodo translate() 96
U
Unity3D documentacin de referencia URL 132 entidad UnityFlockController 90 UnityF
lock.cs ile 91 UnityFlock script 90, 97 Unity Pro 143 Unidad de documentacin de r
eferencia URL 146 isla Unitys Demo condenacin desde 89, 90 Mtodo Update 82, 83, 11
3, 117, 118, 120, 191, 206 el mtodo Update() de 93, 100, 103 UpdateRandom() mtodo
93 mtodo UpdateSense 83, 85
V
Vector3.mtodo RotateToward 96 vehculos 189
W
194 WandarPoints errante.cs ile 81 errante script 82 waypoints configurar 37 cla
se clase WeaponMissile WeaponGun 191 205 armas acerca de 199 bullet objeto pisto
la 201-203 200, 201 launcher Arma 205 205, 206 misiles weightedReelPoll lista de
matriz del flujo de trabajo 161-163 70
[ 213 ]

Gracias por comprar la unidad 4.x juego AI Programacin


Sobre Editorial Packt
Packt, pronunciado "lleno", public su primera obra "Dominar phpMyAdmin para una e
ficaz administracin de MySQL" en abril de 2004 y continu posteriormente a especial
izarse en la publicacin de libros altamente concentrados en speciic tecnologas y s
oluciones.
Nuestros libros y publicaciones compartir las experiencias de sus compaeros profe
sionales de TI en la adaptacin y personalizacin de sistemas, aplicaciones y marcos
actuales. Nuestra solucin basada en los libros le dan el conocimiento y el poder
para personalizar el software y las tecnologas que est usando para hacer el traba
jo. Packt libros son ms speciic y menos generales que los libros que usted ha vis
to en el pasado. Nuestro modelo de negocio exclusivo nos permite ofrecerle una i
nformacin ms especfica, que te da ms de lo que usted necesita saber y menos de lo qu
e no.
Packt es una moderna, pero nico Publishing Company, que se centra en la produccin
de calidad, de vanguardia libros para comunidades de desarrolladores, administra
dores, y novatos por igual.
Para obtener ms informacin, visite nuestro sitio web: www.packtpub.com.
Escrito por Packt
celebramos todas las preguntas de las personas interesadas en la edicin. Reserve
las propuestas deben enviarse a Author@packtpub.com. Si tu libro idea est todava e
n una etapa temprana y que le gustara discutir irst antes de escribir un libro fo
rmal propuesta, pngase en contacto con nosotros; uno de nuestros editores se pond
r en contacto con usted.
No slo estamos buscando autores publicados; si tiene slidos conocimientos tcnicos p
ero sin experiencia literaria, nuestros editores experimentados pueden ayudarle
a desarrollar una carrera de escritor, o simplemente obtener alguna recompensa a
dicional por su experiencia y conocimientos.

Unidad 3.x Scripting


ISBN: 978-1-84969-230-4 Rstica: 292 pginas
eficient escribir scripts reutilizables para crear personajes personalizados, am
bientes de juego y controlar el enemigo AI en su unidad juego
1. Hacer tus personajes interactan con los botones y el programa genera secuencia
s de accin
2. Crear personajes personalizados y cdigo de objetos dinmicos y jugadores' la int
eraccin con ellos
3. Sincronizar el movimiento de carcter ambiental y objetos
4. Agregar y controlar las animaciones con personajes nuevos y existentes de la
unidad 3.x el Desarrollo de juegos Essentials
: ISBN 978-1-84969-144-4 Rstica: 488 pginas
construir totalmente funcional, con juegos 3D profesionales de entornos realista
s, sonido, efectos dinmicos, y ms!
1. Comience el desarrollo de juegos, y construir listos para jugar a juegos 3D c
on facilidad.
2. Comprender los conceptos fundamentales en el diseo del juego incluyen scriptin
g, la fsica, la instanciacin, efectos de partculas y mucho ms.
3. Probar y optimizar su juego a la perfeccin con la imprescindible consejos y tr
ucos.
4. Aprender el juego en la unidad de desarrollo de la versin 3 y anteriores, y ap
render scripting en C# o
compruebe www.PacktPub.com JavaScript para obtener informacin sobre nuestros ttulo
s

Unidad 3 Desarrollo del juego Hotshot


ISBN: 978-1-84969-112-3 Rstica: 380 pginas
speciically ocho proyectos diseados para explotar todo el potencial de la unidad
1. Fresca, divertida, aspectos avanzados de la Unidad de Desarrollo de juegos, d
esde la creacin de un lanzador de cohetes para construir su propio mundo de juego
destructible
2. Master Unidad avanzadas tcnicas como la programacin de sombreado de superficie
y de programacin de IA
3. Programacin de la unidad de lite para quienes buscan tomar sus habilidades al s
iguiente nivel
Unity 3.x el Desarrollo de juegos por ejemplo Beginner's Guide
ISBN: 978-1-84969-184-0 Rstica: 408 pginas
Un asiento-de-su-pantalones manual para construir la diversin, groovy juegos pequ
eos rpidamente con Unity 3.x
1. Crear divertidos juegos gratis utilizando el motor de juego de Unity, incluso
si nunca has codifican antes del
2. Aprender a "piel" proyectos para hacer juegos totalmente diferentes de la mis
ma ile - ms juegos, menos esfuerzo!
3. Implementar sus juegos a travs de Internet para que sus amigos y familiares po
drn jugar con ellos
4. Repleto de ideas, inspiracin y consejos para su propio desarrollo y diseo de ju
ego
Por favor compruebe www.PacktPub.com para obtener informacin sobre nuestros ttulos