Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Sobre Unity PDF
Sobre Unity PDF
2013-2014
Desarrollo de un videojuego de aventuras en C# sobre Unity
Resumen
El objetivo de este proyecto es crear un videojuego del tipo RPG de aventuras
para dispositivos Android. Todo el desarrollo se ha realizado desde cero y se han
implementado un nivel, tres personajes jugables, tres enemigos diferentes y
varias zonas especiales. Se empleó el motor de juego Unity3D y el código fue
escrito en C#.
Abstract
The project's goal is to create a RPG adventure video game for Android. All
the development has been made from scratch, and a level, three playable
characters, three different enemies and some special zones have been
implemented. We used Unity as game engine and the code was written in C#.
2
Tabla de contenidos
1. Introducción ...............................................................................................................5
1.1. Motivación ..........................................................................................................5
1.2. Objetivos .............................................................................................................5
2. Selección de herramientas .........................................................................................7
2.1. Motor de juego ....................................................................................................7
2.2. Lenguaje de programación ................................................................................ 8
2.3. Plataforma objetivo............................................................................................ 8
3. Introducción a Unity3D ............................................................................................ 9
4. Análisis ..................................................................................................................... 13
5. Diseño....................................................................................................................... 18
5.1. Aspecto conceptual ........................................................................................... 18
5.2. Aspecto estructural ........................................................................................... 21
5.3. Aspecto gráfico .................................................................................................. 21
6. Implementación ...................................................................................................... 23
6.1. Mánagers ......................................................................................................... 23
6.2. Personajes .........................................................................................................27
6.2.1. Héroe .............................................................................................................27
6.2.2. Enemigos ...................................................................................................... 29
6.3. Interfaz gráfica ................................................................................................. 30
6.4. Estructuras de datos ........................................................................................ 33
6.5. Utilidades ......................................................................................................... 34
7. Pruebas realizadas................................................................................................... 35
7.1. Ordenadores .................................................................................................... 36
7.2. Dispositivos móviles .........................................................................................37
8. Conclusiones ........................................................................................................... 38
8.1. Relación con la carrera .................................................................................... 38
8.2. Dificultades encontradas ................................................................................. 39
8.3. Resultados........................................................................................................ 39
9. Trabajo futuro ......................................................................................................... 39
Bibliografía ..................................................................................................................... 42
Anexos ............................................................................................................................ 44
3
Desarrollo de un videojuego de aventuras en C# sobre Unity
4
1. Introducción
Motivación
Uno de los productos más demandados últimamente en todo el mundo,
desafiando las dificultades económicas actuales, son los videojuegos, cuyas
ventas siguen creciendo año tras año [7]. En una tesitura similar a la de los
videojuegos podemos encontrar a los dispositivos móviles: tablets y
smartphones [8]. Desde hace unos años, este tándem videojuegos-dispositivos
móviles ha ido fortaleciéndose mutuamente a un ritmo acelerado gracias a la
gran cantidad de desarrolladores que aportan sus juegos y a que mucha gente
quiere ocupar pequeños ratos libres en actividades lúdicas que pueda empezar
y terminar en breves espacios de tiempo.
A todo esto ha contribuido la cultura que se está creando en Internet y las
nuevas herramientas que tratan de agilizar el proceso de creación del software,
ahorrando así meses de trabajo y reduciendo el tiempo de aprendizaje de las
anteriores herramientas. Unity es una de estas nuevas herramientas.
La motivación personal que ha propiciad la realización de este proyecto ha sido,
principalmente, el interés en trabajar en un futuro en esta área laboral. Con él
se pretende realizar un acercamiento a los diferentes aspectos de la creación de
un videojuego, desde el diseño hasta la implementación.
Por otra parte, se ha observado que en la Play Store 1 existe una gran
competencia en juegos arcade y sociales, como los creados por King o Gameloft,
pero se observa una carencia de juegos similares a los que se pueden encontrar
en videoconsolas portátiles, como la PlayStation Portable o la Nintendo DS. Las
anteriores y la afición por este tipo de juegos han sido las principales razones
que han propiciado la elección de este trabajo.
En cuanto a la temática, un ambiente post-apocalíptico nos permite introducir
una gran variedad de situaciones diferentes. Como jugadores de videojuegos y
espectadores de películas de esta temática, se ha observado la gran cantidad de
oportunidades que ofrece esta situación. Oportunidades que pueden desatar
diferentes sentimientos. Se pueden encontrar desde situaciones cómicas hasta
algunas realmente trágicas.
Objetivos
La finalidad de este proyecto es la de desarrollar un videojuego de aventuras-
RPG para dispositivos móviles con sistema operativo Android, aprendiendo en
1 Servicio de Google que recoge la mayoría de las aplicaciones para Android
5
Desarrollo de un videojuego de aventuras en C# sobre Unity
6
2. Selección de herramientas
Motor de juego
En la actualidad se pueden encontrar una gran variedad de motores de juego,
cada uno con sus características distintivas, sus ventajas y sus inconvenientes.
Entre todos ellos se han tenido en cuenta los que se centraban en el desarrollo
de videojuegos para dispositivos móviles.
Corona SDK es una herramienta centrada en el desarrollo de juegos en 2D para
móviles y tablets creada por Corona Labs Inc. Posee un gran catálogo de librerías
para ayudar en la programación de diversos aspectos, y permite su uso de forma
gratuita, sacrificando el uso de ciertos aspectos reservados a los usuarios de
pago. Utiliza el lenguaje de script Lua y es cross-platform (el mismo código sirve
para varias plataformas). Major Magnet, Blast Monkeys, The Lost City y Freeze!
son algunos de los videojuegos que lo han usado.
Marmalade C++ SDK, de Marmalade Technologies Ltd., es un motor cross-
platform que permite programar videojuegos para una gran variedad de
dispositivos usando C++, acelerando dicho proceso gracias a sus librerías.
Algunos videojuegos programados con Marmalade SDK son Godus, Draw
Something, Plants vs Zombies y Vector.
Cocos2d-x es un motor de juego de código abierto desarrollado por el MIT.
Facilita el desarrollo de videojuegos para cualquier plataforma con C++, Lua o
Javascript. También posee potentes características que lo hacen una buena
elección frente a otros. Badland, Castle Clash, Star Wars: Tiny Death Star y
Family Guy: The Quest for Stuff, entre otros, lo han empleado.
Unity3D (Unity) es propiedad de Unity Technologies, y actualmente es uno de los
motores de juego más importantes y extendidos. Permite utilizar Javascript3,
Boo y C#, y dispone de un editor que agiliza el desarrollo del videojuego.
También posee una amplísima comunidad, que ayuda a resolver dudas y crea
plugins para cubrir aspectos puntuales del desarrollo, algunos de los cuales son
muy potentes y su uso está muy extendido. Entre todos los videojuegos que se
han desarrollado usándolo podemos destacar algunos: Monument Valley, The
Forest, Oddworld: New ‘n’ Tasty, Rust y Broforce.
Finalmente se decidió emplear Unity, pese a las similitudes entre todos, debido
a su fuerte comunidad que proporciona apoyo ante cualquier duda, crea
tutoriales para ayudar a realizar ciertas tareas y plugins 4 que cubren o
7
Desarrollo de un videojuego de aventuras en C# sobre Unity
Lenguaje de programación
Una vez elegido Unity como motor de juego se debía escoger un lenguaje de
programación. Este motor permite emplear Javascript, Boo y C#, incluso a la
vez. Debido a recomendaciones de los foros de Unity que indicaban que utilizar
ambos en un mismo proyecto propiciaba que éste fuese propenso a errores, ya
que habría que tener en cuenta el orden de ejecución y de compilación de cada
script, se descartó rápidamente esta opción. Boo, un lenguaje OO5 inspirado en
Python, también fue descartado al principio debido a la falta de apoyo por parte
de la comunidad.
Teniendo en cuenta que C# presentaba una sintaxis mucho más similar a la de
Java, un lenguaje OO con el que se ha trabajado en gran parte de la carrera, se
decidió utilizar éste. Además proporciona un mayor control, aunque esto mismo
exija una mayor responsabilidad por parte del programador. Por último, y para
reforzar la decisión, se consultó algunas fuentes digitales (principalmente foros)
y libros, y la mayoría recomendaban C# [9].
Plataforma objetivo
Debido al auge de los dispositivos móviles es una gran oportunidad sacar un
videojuego centrándose en ellos. Android e iOS son los SO6 mayoritarios, sin
ningún rival que suponga una amenaza real ahora mismo.
iOS presenta una gran base de usuarios, y la monetización de sus aplicaciones
es mayor a la de Android. Pese a ello, presenta algunas dificultades generales
como son el requisito indispensable de poseer una licencia de pago para
desarrollar aplicaciones para ella y las rígidas reglas de diseño que exigen.
Además de ello, se requiere un ordenador con OS X para compilar la aplicación.
Android fue la elección debido a que, además de lo anteriormente dicho, sólo se
disponía de dispositivos con Android, y eran necesarios para realizar las pruebas
y asegurarnos que realmente funcionaba todo correctamente.
Pese a haberse decidido a utilizar Android, dado que Unity permite el desarrollo
cross-platform, el código desarrollado podrá ser empleado, si no en su totalidad
en gran medida, en la creación de la versión para iOS o, incluso, para Windows
Phone, Linux, OS X y consolas.
5 Orientado a objetos
6 Sistema operativo
8
3. Introducción a Unity3D
Unity se fundamenta en unos objetos llamados GameObjects. La mayoría de los
elementos del juego, desde los scripts hasta elementos gráficos suelen depender
de ellos.
Empezando por el principio, se introduce el concepto Scene. Una Scene es un
entorno donde se desarrolla una parte del juego, incluyendo menús, ya que todo
debe estar dentro de una. A menos que se especifique lo contrario, todos los
elementos contenidos en un Scene se eliminan cuando se cambia a otra Scene.
En la Ilustración 1 se puede observar una Scene con unos elementos (personajes,
terreno, cámara, iluminación, …) que formarán parte del juego. Una cuestión
importante a tener en cuenta es que el editor sólo es una ayuda, y no por verse
bien en la ventana de Scene se va a ver bien en el juego, ni al contrario, pues
pueden existir scripts que cambien completamente el comportamiento de los
elementos de la Scene, incluyendo a la cámara y componentes de renderizado.
9
Desarrollo de un videojuego de aventuras en C# sobre Unity
8 Actualización de la pantalla
9 Métodos que se ejecutan cuando un evento determinado es lanzado
10
que resultan muy útiles para controlar colisiones, entradas de usuario, eventos
de renderizado, eventos del sistema, etc.
Una vez introducida la clase MonoBehaviour, podemos pasar a descubrir el flujo
de ejecución de los scripts. Debido a que Unity Technologies no proporciona una
documentación clara en este aspecto, algunos usuarios han experimentado
hasta encontrar el ciclo de vida de los scripts (véase Ilustración 3). Awake(),
Start() y Update() son los métodos más empleados, pues sirven para inicializar
los objetos y actualizarlos a lo largo de la ejecución del juego. Awake() se emplea
para inicializar los propios atributos, independientes de los demás objetos.
Start(), cuyo funcionamiento es muy similar al Awake() pero que se ejecuta
posteriormente, se suele utilizar para inicializar variables que dependen de otros
métodos y que ya habrán sido preparadas en el Awake(). En cuanto a Update(),
se ejecuta después de las anteriores, y a diferencia de éstas se ejecutará
continuamente. Se emplea para actualizar estados y atributos, modelando el
comportamiento de los objetos a lo largo de la ejecución.
Otra característica muy útil que nos proporciona MonoBehaviour son las
corrutinas. Se trata de métodos especiales que permiten retrasar la ejecución un
tiempo determinado y que se ejecutan en paralelo al resto del código, resultando
útiles, por ejemplo, para programar algunas animaciones. Estas corrutinas
tienen la peculiaridad, respecto al resto de métodos, de que no dejan de
ejecutarse aunque el script que las contenía se desactive. No se ejecutan como
métodos normales, sino mediante el método StartCoroutine(), y se detienen
cuando terminan de ejecutar su código o mediante una llamada a
StopCoroutine().
A parte de las anteriores herramientas, que se pueden considerar más técnicas
y enfocadas al comportamiento del juego, Unity posee otras características muy
interesantes. Todo esto lo convierte hoy en día en un motor muy empleado por
una gran variedad de empresas y desarrolladores independientes. Como se
puede observar en la información proporcionada por Unity [13], que se basa en
muchos casos en informes y estadísticas externas como se puede observar en
las fuentes citadas, este motor presenta una gran penetración en el mercado y
casi (un 47%) de los desarrolladores de juegos han empleado Unity alguna vez
mientras que un 29% lo emplea como su motor principal. Además, su base de
desarrolladores registrados asciende a más de 3,3 millones, lo que resulta posible
gracias a su política de licencias, que permite a cualquier desarrollador utilizar
Unity para crear su juego gratuitamente, sacrificando algunas características
secundarias como la posibilidad de usar un servidor que gestione el proyecto
para un desarrollo concurrente o algunas opciones gráficas avanzadas. La
licencia gratuita también limita el volumen de ventas e ingresos siendo que si
alguno de estos se supera, se debe comprar la versión completa (Unity3D Pro).
11
Desarrollo de un videojuego de aventuras en C# sobre Unity
12
4. Análisis
Al comenzar el proyecto se realizó un proceso para prepararlo, estableciendo
las necesidades y la planificación que se seguiría. Esta es la primera fase del
proyecto que precederá al diseño y a la implementación.
Primero se realizó una planificación aproximada del tiempo del proyecto,
representado mediante un diagrama de Gantt (véase Figura 1), que después
permitiría realizar una comparación con el tiempo que finalmente dedicamos a
cada apartado (véase Figura 2).
A la fase de diseño, formada por el diseño de la estructura de clases y al de las
estructuras de datos, se decidió darle un tiempo considerable, 12 días, aunque
finalmente se empleó un tiempo menor, 10 días. Esto fue debido a que no fue
necesario diseñar varias clases para los enemigos, ya que lo único que cambian
entre ellos son los atributos que permiten modificar la fuerza y frecuencia de su
ataque, la defensa, la vida y la experiencia. También se comprobó que el cálculo
inicial del tiempo, que se estimó en 12 días debido a la dificultad que
pensábamos que nos podía presentar este proceso, fue menor porque las pautas
aprendidas en la carrera agilizaron el proceso.
La implementación fue la que consumió la mayor parte del tiempo. Ya desde el
principio se pensaba que así sería, y aun así el cálculo resultó ser demasiado
optimista. Se le otorgaron 34 días, pero finalmente ocupó 52, pues surgieron más
problemas de diversa índole que no se esperaban, algunos de ellos relacionados
con el uso de Unity, como el control de la interfaz y algunos aspectos de la
persistencia de los datos.
También se tuvo en cuenta una fase extra dedicada a solucionar errores y fallos
menores, pues al programarlo en un ordenador, el resultado era susceptible a
no funcionar de la misma manera en un dispositivo móvil. A esta fase se le
asignaron 6 días, pero finalmente, y debido a la demora en la implementación,
se alargó hasta los 12.
Después se observaron videojuegos similares para visualizar la magnitud del
proyecto completo. Tras esto, se decidió que se recortarían algunos aspectos y
se añadirían otros para dar cabida al proyecto en el tiempo disponible y
centrarse más en los aspectos informáticos del proyecto, dejando en segundo
lugar a los más visuales y artísticos. Entre los aspectos recortados se encuentran
muchos aspectos gráficos, como efectos visuales y sonoros, pues quedaban fuera
de lo que nos interesaba mostrar en este proyecto. Principalmente los efectos
eliminados (o pospuestos para futuras actualizaciones) son la inclusión de
efectos sonoros en los ataques recibidos y realizados en combate, un efecto
visual y sonoro cuando el enemigo o el héroe realiza un ataque o lo recibe, otro
13
Desarrollo de un videojuego de aventuras en C# sobre Unity
14
Para controlar gran parte de juego se pensó en una máquina de estados que
controlara diversos eventos como la aparición de los enemigos o el flujo del
combate. Esta máquina debía cubrir las necesidades del juego, permitiendo
gestionar los sucesos y las acciones que tendrían lugar al ejecutar el juego, al
desplazarse por el mapa, al entrar en un combate, a salir de éste, etc. La máquina
resultante de dicho análisis se puede encontrar en el Diagrama 2. Por defecto, el
estado inicial es “null”. Una vez se inicializa el héroe, su estado pasa a
“standing”, que se trata del estado que indica que el jugador no está en una
batalla y su personaje está quieto. La única forma de cambiar esto es que el
personaje se desplace, con lo que su estado cambiaría a “exploring”, que expresa
que el jugador está moviéndose. Ese estado se mantendrá mientras no separe,
con lo que volvería al “standing” o mientras no aparezca un enemigo, momento
en el cual el estado pasaría a ser “waiting”, que es el estado encargado de, en
una batalla, impedir que el jugador realice ninguna acción y espere su turno de
atacar. Desde este estado pueden suceder dos cosas: que se termine el tiempo de
espera y pasemos al estado “attack” que indica que ya se puede atacar y
desbloquea las acciones pertinentes o que el enemigo nos derrote y pasemos al
estado “defeat”. En el primer caso, podrán darse tres transiciones: que el jugador
decida atacar o defenderse, con lo que volveríamos al estado “waiting”, que el
jugador decida huir, con lo que pasaríamos al estado “standing”, que el jugador
sea derrotado e iría al estado “defeat” y por último, que el jugador ataque y
derrote al enemigo, con lo que pasaríamos al estado “victory”. El estado
“victory” se encarga de procesar la victoria, otorgar recompensas y demás
acciones a tomar cuando el jugador gana un combate. Una vez haya terminado
de procesarla, el estado pasa a ser “standing” de nuevo. Si el jugador es
derrotado y nos encontramos en el estado “defeat”, la partida se carga
automáticamente desde el último punto guardado.
15
Desarrollo de un videojuego de aventuras en C# sobre Unity
16
Figura 2. Diagrama de Gantt (agosto 2014) Figura 1. Diagrama de Gantt (junio 2014)
17
Desarrollo de un videojuego de aventuras en C# sobre Unity
5. Diseño
La creación de un videojuego requiere un diseño a varios niveles. Se necesita
saber cómo va a ser el videojuego, el concepto, que se describirá en un
documento de diseño del videojuego (GDD, Game Design Document)10 y cómo
se va a programar y qué clases van a ser necesarias. Para explicar este proceso,
se ha dividido el aspecto de la programación en dos partes, ya que se ha
considerado que el diseño de la interfaz es una parte suficientemente extensa y
diferenciada de la lógica interna del resto de clases como para formar otro
punto.
Aspecto conceptual
El videojuego se puede clasificar como un RPG de aventuras. El jugador se crea
un personaje, escogiendo entre tres clases diferentes para lograr diferentes
estilos de juego para ofrecer variedad. Estas clases son las siguientes:
Engineer: es más resistente que los demás, por lo que resiste más ataques
antes de morir pero tarda más en eliminar con los enemigos.
Magician: su ataque es superior al de los demás, pero es menos resistente.
Technomancer: su resistencia y ataque están equilibrados, situándose en el
medio entre las otras dos clases.
A cada tipo de héroe, para conseguir estos efectos, cuando es creado se le
asignan unos atributos diferentes. Estos atributos se actualizarán cuando se sube
de nivel, mejorándose.
El jugador puede desplazar a su héroe a lo largo y ancho del mapa. Cada cierto
tiempo aleatorio, un enemigo aparecerá. Este enemigo será elegido por el
sistema aleatoriamente entre tres tipos diferentes, donde cada enemigo puede
ser configurado independientemente de los otros para otorgar variedad al
jugador. Además, los enemigos se hacen más fuertes de acuerdo al nivel del
héroe. Si el héroe consigue derrotar a su rival, ganará experiencia que le servirá
para aumentar de nivel. Si por el contrario pierde, se cargará la partida desde el
último punto guardado. Siempre, si prevé su derrota, el jugador puede optar por
huir de la batalla, quedándose con la vida que posee en el momento de huir pero
no obteniendo ninguna recompensa. Para recuperar la salud perdida el jugador
puede subir de nivel o acudir a ciertos lugares repartidos por el mapa que poseen
un aspecto de un ankh11.
18
En cuanto a la secuencia de pantallas, se ha tratado de conseguir un diseño
consistente y flexible, de forma que se puedan añadir nuevos pasos a la
secuencia. Un diagrama de flujo puede observarse en el Diagrama 4, mostrando
las diferentes transiciones posibles entre las pantallas. Se puede observar cómo
no es posible crear un personaje y ponerse a jugar si únicamente se ha
seleccionado el job y no se le ha puesto nombre, o cómo la única forma de volver
al menú principal desde el juego es abrir el menú in-game estando en Game
(explorando el mundo, sin estar en combate) y pulsar en Exit.
19
Desarrollo de un videojuego de aventuras en C# sobre Unity
20
Aspecto estructural
Las clases empleadas en el proyecto se pueden dividir en tres grupos: los
managers, clases básicas y clases de interfaz de usuario (GUI, graphic user
interface en inglés).
Los managers son clases encargadas de gestionar a grupos de objetos que
comparten una clase básica como por ejemplo los enemigos, facilitando el
acceso a todos a través de éste y permitiendo la aplicación directa de efectos a
todos a la vez. Esto se consigue, normalmente, añadiendo todos los elementos
de un mismo tipo es una estructura, de forma que cuando se desea aplicar a
todos los elementos una función o modificarlo de alguna forma, se itera a través
de esta aplicándolo uno a uno, sin necesidad de buscarlos por todo el código.
También controlan los aspectos transversales del juego, como puede ser la
música, el acceso a los datos persistentes, la entrada del usuario, etc. Para
centralizar su acceso y pudiendo realizar cambios sin tener que modificar gran
parte del código.
Las clases básicas son aquellas que contienen el comportamiento de los objetos
o sus atributos. Son muy variadas, desde las clases que contienen la inteligencia
artificial de cada personaje independiente hasta los que controlan las
animaciones por código, cambiando los sprites.
En cuanto a los scripts de UI, son aquellos que se encargan de dibujar cada
elemento de interfaz en la pantalla, gestionando su entrada12 y cambiando para
adaptarse a ella.
Aspecto gráfico
Este es, cara al público, un aspecto realmente importante. Es el aspecto que la
gente ve y que puede modificar totalmente la percepción que tiene el jugador
del juego.
La interfaz es parte importante de un juego. Si es sencilla y consistente facilita
la interacción del jugador con la aplicación [12]. El diseño de la interfaz se ha
realizado tratando de seguir las reglas de oro dictadas por Ben Shneiderman [1]:
1. Consistencia en el diseño. La interfaz mantiene una estructura lo más
similar posible entre ella, para evitar confundir al usuario cambiando
los botones de lugar si su función es similar. Un ejemplo de esto se
encuentra en los menús de creación de personaje con el botón de volver
atrás colocado en la misma posición. Los botones de volumen también
los encontramos situados en el mismo orden.
21
Desarrollo de un videojuego de aventuras en C# sobre Unity
13R.A.E. “Feed-back”: (voz i.) m. Retroalimentación, conjunto de reacciones o respuestas que manifiesta
un receptor respecto a la actuación del emisor, lo que es tenido en cuenta por este para cambiar o
modificar su mensaje:
22
Otra parte importante del diseño gráfico de un videojuego son todos los gráficos
que poseerán los personajes, el mapa y los elementos contenidos en éste. Debido
a que el proyecto no se centra completamente en este aspecto, la aplicación
resultante ha pasado por alto algunos elementos deseables y se ha centrado en
la interfaz. Esto mismo causó que se usaran gráficos ya creados de varias
fuentes. Se buscó que las texturas fuesen de baja resolución (pixeladas) para
otorgar un efecto retro.
Queda por comentar que algunos recursos empleados han sido realizados por
varios artistas distintos. Tanto los sprites de los personajes, el tileset14 empleado
para crear el mapa y la música han sido obtenidos de diversas fuentes, las cuales
se encuentran especificadas en el punto segundo del Anexo. Aun así, algunos
elementos como los iconos de cada job y los demás dibujos se han realizado
dentro del ámbito de este trabajo.
6. Implementación
La implementación ha sido uno de los procesos más costosos, pero a la vez uno
de los que más cosas nos han enseñado. Hemos reforzado nuestro conocimiento
de C# y de Unity, y hemos podido seguir la creación de una aplicación desde la
nada hasta un videojuego jugable.
Esta fase ha sido la más costosa y duradera debido a las diversos cambios en el
diseño que surgieron a lo largo del desarrollo. Estos cambios se debieron
principalmente a la experiencia en el campo de la creación de videojuegos
adquirida en un entorno laboral durante el entorno estival, que tuvo lugar a la
vez que este proyecto avanzaba.
El resultado de la implementación han sido 24 clases que podemos clasificar en
cinco grupos: managers, personajes, interfaz gráfica, estructuras de datos y
utilidades.
Managers
Estas clases formarán la columna vertebral del proyecto. Son las encargadas de
la gestión y el control de otras clases y de aspectos generales como el audio o la
persistencia de datos. Una ventaja importante es que permiten escalar el
proyecto fácilmente, cosa realmente importante en un videojuego ya que
siempre es deseable poder ampliarlo y añadirle nuevas características.
14Se trata de un mapa de imágenes que se emplea para crear escenarios o imágenes más grandes.
Suelen representar objetos o espacios tipo, de forma que si se juntan de forma lógica dibujen un mapa o
una zona deseada. Es muy empelado en juegos con gráficos de 8 bits.
23
Desarrollo de un videojuego de aventuras en C# sobre Unity
Este fragmento gestiona el audio de forma que cuando esta función es invocada,
se encarga de comprobar si ya hay alguna música sonando. Si es así, comprueba
si es la misma que se quiere hacer sonar, en cuyo caso se deja como está para
que siga sonando, pero si la que suena es distinta, se destruye el componente
actual para crear el nuevo componente de audio con la nueva música.
24
Figura 4. Fragmento de código de CDataManager.
25
Desarrollo de un videojuego de aventuras en C# sobre Unity
26
en el que aparecerá el enemigo y prepara el actual combate. Tal preparación
consiste en activar la cámara que renderiza el espacio del combate y desactivar
la principal, habilitar el menú de combate, elegir un enemigo aleatorio y
activarlo y poner al héroe en estado de espera en el combate, dando así comienzo
a éste.
En esta versión únicamente contiene los estados y los tipos de los enemigos
(véase Figura 6). Al ser enemigos relativamente sencillos, constan de pocos
estados. Un estado inicial, otro que indica que está esperando, otro para cuando
ataca, otro más para cuando muere y un último estado para cuando ya ha
muerto.
Personajes
6.2.1. Héroe
27
Desarrollo de un videojuego de aventuras en C# sobre Unity
28
Otra clase relacionada con el héroe es PlayerData. Se trata de una clase
serializable 16 empleada para almacenar los atributos del héroe y alguna
información más, como el tiempo de juego. Además de ser utilizada para el
acceso dentro del juego, como un struct típico, también se emplea para
almacenar la información de forma persistente.
Las animaciones del héroe las controla RunAnimations. Este script cambia el
sprite 17 de acuerdo a ciertos parámetros: la frecuencia de actualización, que
indica la velocidad de cambio entre un conjunto de sprites (véase Figura 9). Otro
parámetro es el estado del héroe, que indica si debe estar alternando sus sprites
(está moviéndose) o no (está quieto). Esta clase emplea el vector devuelto por
CInputManager para saber qué grupo de sprites debe estar alterando si están
activos o no sus miembros.
6.2.2. Enemigos
CEnemyBasic es la clase que modela el comportamiento de los enemigos que
encontramos en el juego. Emplea una máquina de estados para controlar qué
debe hacer en cada momento, que se encuentra en la clase CEnemyManager
(véase Figura 6), ya que la emplearán futuros enemigos con diferentes scripts de
comportamiento, como los jefes. Esta clase también gestiona las animaciones
que se reproducen al recibir daño, así como también prepara al enemigo al
comienzo de la batalla, lo escala para igualar su fuerza a la del héroe y gestiona
los ataques y el daño recibido.
Como se puede ver en las Figuras 10 y 11, el comportamiento básico del enemigo
es el de esperar hasta que pueda atacar y, entonces, atacar. Tras atacar, se vuelve
a poner en espera. Este comportamiento será cíclico hasta que la batalla termine.
Esta estructura nos permite añadir fácilmente un nuevo estado o modificar los
actuales para cambiar el comportamiento del enemigo,
16 Al marcar una clase como serializable, el compilador almacena todas sus variables en un espacio
continuo de memoria, permitiendo que se pueda volcar en un fichero directamente.
17 Aunque en su origen se trataba de un tipo de mapa de bits especial para reducir la carga del procesador,
29
Desarrollo de un videojuego de aventuras en C# sobre Unity
Interfaz gráfica
30
La implementación de la interfaz ha sido realizada enteramente mediante
código. Cada escena tiene su propio script encargado de dibujarla, y dentro del
juego podemos encontrar varios, para los diferentes elementos.
En las escenas del menú principal, los menús de creación de personajes, el menú
de opciones y el de información 18 cuentan con unos scripts muy similares,
cambiando el número y la posición de los elementos y añadiendo o eliminando
alguno. Estos scripts siempre están activos, pues el menú siempre debe estar
activo. Un ejemplo se puede observar en la Figura 12.
Por otra parte podemos encontrar la interfaz una vez empezada la partida. Para
controlar la barra inferior que encontramos al entrar en la partida (véase Figura
13) empleamos la clase CHud. Aquí se controla la barra de vitalidad del
personaje, el nombre, el nivel y el botón que abre el menú in-game19 (véase
Figura 14).
31
Desarrollo de un videojuego de aventuras en C# sobre Unity
32
cuando el jugador no puede actuar. También se desactiva el botón de menú, para
impedir situaciones no deseadas.
Por último, la vida del enemigo también forma parte de la interfaz (véase Figura
16). En este caso concreto, este elemento de la interfaz lo controla cada enemigo.
Estructuras de datos
La información debe estar organizada en estructuras de forma que faciliten los
accesos y su modificación. En este caso encontramos principalmente tres
estructuras.
La primera estructura es el fichero XML encargado de la configuración de los
enemigos. Especifica la vitalidad, el daño de ataque, su defensa, la frecuencia de
ataque y la experiencia que otorga cada uno (véase Figura 17). Este fichero se
puede editar sin tocar nada del código, facilitando así su edición por parte de
personas no acostumbradas a programar. Se analiza este fichero (comúnmente
llamado parsear) mediante la clase CDataManager y se traspasa su contenido a
un struct 20 , evitando tener que acceder continuamente a un fichero externo,
evitando así costes innecesarios.
33
Desarrollo de un videojuego de aventuras en C# sobre Unity
Utilidades
Para facilitar el funcionamiento de los demás scripts, se decidió implementar
unas clases que servirían para resolver problemas muy puntuales de forma
similar a las API de cualquier lenguaje.
34
La primera clase creada de esta categoría es CUtils, que incluye diferentes
funciones como la de cambiar un único elemento de un vector sin tener que
pasar por escribir un código de varias líneas, haciéndolo sólo aquí. Se observó
que esto era una tarea muy recurrente y que era susceptible de ser
implementada en una clase que sirviese como contenedor de herramientas.
Por otra parte, se ha programado una pequeña clase con funciones que permiten
testear ciertos aspectos del juego rápidamente. Actualmente permite aumentar
y disminuir la vida del héroe para probar ciertos elementos relacionados con
ésta. Por otra parte, permite implementar nuevas funciones de testeo fácilmente.
Mejoras de optimización
Existe la creencia de que nos dispositivos de hoy en día son tan potentes que la
optimización no es necesaria. Si bien es cierto en parte, y dependiendo de la
aplicación, que ya no es tan necesario como antes este proceso, realizarlo puede
mejorar la fluidez y evitar que el dispositivo se caliente innecesariamente. En
este proyecto se han aplicado algunas características que proporciona Unity
para tratar de mejorar el rendimiento.
Usualmente se debe escoger entre optimizar el uso del procesador cargando más
la memoria o liberar memoria a costa del procesador. En este caso se ha decidido
cargar la memoria debido a que la carga no es grande. Se ha logrado gracias a la
característica de Unity que nos permite desactivar objetos, lo que permite que
sigan existiendo en memoria, con lo que no deberán ser creados y evitando la
consecuente carga del procesador, pero no interactúan en la partida. El ejemplo
más notorio de esto se encuentra en el combate: todos los elementos del combate
(excepto la interfaz, que va por código y no puede estar precargada), desde la
cámara hasta los enemigos pasando por el fondo, están ya cargados en memoria
desde el inicio de la partida, pero desactivado. Cuando se les necesita, se activan
los elementos solicitados y se ponen en funcionamiento.
Por supuesto, cuando la cámara que renderiza el combate se activa, la cámara
principal se desactiva para evitar que renderice en vano.
7. Pruebas realizadas
Para comprobar el correcto funcionamiento de la aplicación se han empleado
cuatro dispositivos con diferentes características: dos ordenadores y dos
móviles.
35
Desarrollo de un videojuego de aventuras en C# sobre Unity
Ordenadores
Las pruebas en los ordenadores se realizaron para comprobar la capacidad cross-
platform que anunciaba Unity, además de que resultaba más rápido realizar las
pruebas en el mismo sistema en el que se estaba programando que tener que
crear el apk21 y pasarlo a un dispositivo externo.
Como ya se ha comentado, dispusimos de dos computadores diferentes:
Ordenador 1:
SO: MS Windows 8.1 64 bits
Procesador: AMD A10-5750M a 2,50 GHz
Gráfica: AMD Radeon HD 8970M
RAM: 8,00 GB
Ordenador 2:
SO: MS Windows 7 64 bits
Procesador: Intel Core i5-2400 a 3,10 GHz
Gráfica: AMD Radeon HD 7750
RAM: 8,00 GB
36
Figura 18. Captura del juego con resolución 1024x768 (4:3).
Dispositivos móviles
Los dispositivos móviles disponibles para las pruebas fueron:
37
Desarrollo de un videojuego de aventuras en C# sobre Unity
8. Conclusiones
Unity ha supuesto un elemento clave en el desarrollo de este proyecto. La
simplicidad, frente a otros motores de juego, es bastante notable. En anteriores
proyectos, en los que no se había empleado Unity, el coste de desarrollo fue
mucho mayor y el resultado final fue mucho peor. Ha permitido desarrollar una
aplicación que funciona perfectamente en dispositivos tan dispares como un
ordenador y un smartphone Android. Pese a estas ventajas, el proyecto no ha
estado exento de problemas pues algunos aspectos no han funcionado como se
esperaba y han requerido ajustes posteriores.
22Por experiencias personales en otros proyectos, pueden presentarse problemas con GPUs concretas,
sin importar la gama de ésta
38
Dificultades encontradas
Pese a todo lo anterior, y debido a la falta de experiencia en este tipo de
proyectos, han surgido dificultades notables. La principal ha sido la
estructuración del código. A lo largo del desarrollo se ha tenido que cambiar el
diseño de clases varias veces debido a diferentes problemas que han ido
surgiendo y a la experiencia adquirida en la empresa, en la que se ha observado
cómo se debía crear un videojuego. Eso podría haberse evitado mejorando la
planificación previa, pero sobretodo con más experiencia en este tipo de
proyectos. Otro gran problema ha sido el de programar la interfaz. Como se ha
dicho en el apartado Introducción a Unity3D, este motor presenta una debilidad
frente a otros motores en este aspecto. Usualmente se suele cubrir con el uso de
plugins, pero se decidió no emplearlos para entender mejor el funcionamiento
de Unity. La decisión de escoger Android también ha acarreado dificultades: está
presente en una gran variedad de dispositivos con una gran variedad de
resoluciones diferentes y aspect ratio23.
Resultados
Aun así, el resultado ha sido bastante satisfactorio (en el tercer punto del Anexo
se pueden encontrar algunas capturas del resultado final). Personalmente, he
aprendido otro lenguaje, C#, que me ha resultado bastante cómodo y potente.
También he profundizado en cómo debe funcionar un videojuego internamente,
y este conocimiento me ayudará a atajar problemas en futuros proyectos. He
observado la importancia de una buena planificación inicial, creando una
estructura consistente pero flexible a la vez, abierta a pequeños cambios de
diseño.
Por último me gustaría recomendar el uso de Unity a cualquiera que desee crear
un videojuego sin disponer de los recursos de una gran empresa, pues permite
crear desde juego sencillo hasta verdaderas maravillas, aunque no alcance la
potencia de otros motores como Unreal Engine o CryEngine.
9. Trabajo futuro
El juego se diseñó para ser mucho más grande, pero debido a la falta de tiempo
se han tenido que recortar algunos aspectos. La estructura está montada y
preparada para dichas implementaciones, que son la inclusión de misiones,
39
Desarrollo de un videojuego de aventuras en C# sobre Unity
24Non-player character, “personaje no jugador”, se refiere a aquellos personajes que no maneja ningún
jugador externo al propio juego.
40
41
Desarrollo de un videojuego de aventuras en C# sobre Unity
Bibliografía
[1] B. Shneiderman, Designing the user interface, Pearson Education India, 2003.
[5] Corona Labs, «Corona Docs,» 31 julio 2014. [En línea]. Available:
http://docs.coronalabs.com/. [Último acceso: 22 agosto 2014].
[7] R. van der Meulen y J. Rivera, «Gartner,» 29 octubre 2013. [En línea]. Available:
http://www.gartner.com/newsroom/id/2614915. [Último acceso: 23 agosto
2014].
[11] M. Fowler, UML Distilled: A Brief Guide to the Standard Object Modeling
Language, Addison-Wesley Professional, 2004.
[14] . J. Schell, The Art of Game Design: A book of lenses, CRC Press, 2008.
42
[15] T. Fullerton, Game Design Workshop: A Playcentric Approach to Creating
Innovative Games, CRC Press, 2008.
43
Desarrollo de un videojuego de aventuras en C# sobre Unity
Anexos
1. Documento de diseño – Hero of Lonetown .................................................. 45
44
Anexo 1
Documento de diseño
Hero of Lonetown
por Alberto Fuentes Agustí
45
Desarrollo de un videojuego de aventuras en C# sobre Unity
Índice
46
2.2.3. Objetos varios ..................................................................................... 53
2.3. Diseño del mapa .............................................................................................. 53
2.3.1. Lonetown ............................................................................................. 53
2.3.2. Símbolos de sanación ........................................................................ 54
2.3.3. Zonas de jefes y minijefes ................................................................ 54
2.3.4. Áreas de bloqueo ................................................................................ 54
2.4. Diseño de la interfaz ....................................................................................... 55
2.4.1. Menús (fuera del juego) .................................................................... 55
2.4.2. Menús (dentro del juego) .................................................................. 56
2.4.3. Juego...................................................................................................... 56
2.4.4. Batalla ................................................................................................... 56
2.4.5. Diálogos ................................................................................................ 57
3. Recursos ....................................................................................................................... 56
3.1. Audios ................................................................................................................ 57
3.1. Imágenes ........................................................................................................... 57
3.1. Fuentes de texto ............................................................................................... 57
47
Desarrollo de un videojuego de aventuras en C# sobre Unity
1.1.2. El gancho
Conseguir un personaje más fuerte y rescatar a más personas será el aliciente
para jugar, averiguando poco a poco la historia que hay detrás.
1.1.3. Sinopsis
Tras una terrible guerra civil con magia y armas biológicas, la que había sido la
potencia más grande del planeta desapareció junto con parte de los países
vecinos, dejando únicamente tierras yermas, habitadas por espantosas y feroces
criaturas resultado de los experimentos y las sustancias empleadas en las
batallas. Tras varios meses de vagar por las ruinas, uno de los pocos
supervivientes humanos, encuentra un pequeño pueblo donde solicitan
desesperadamente ayuda. Las bestias atacaban continuamente, raptando y
destrozando a quienes encontraban a su paso. El recién llegado acepta a cambio
de un lugar donde vivir y recursos. A partir de entonces empezará el
resurgimiento del que posiblemente sea el último asentamiento humano del
país, Lonetown.
1.1.4. Género
Podría clasificarse como un juego de aventuras y rol por turnos.
48
1.1.6. Motor y editor
Se empleará Unity configurado para videojuegos 2D y MonoDevelop como IDE.
49
Desarrollo de un videojuego de aventuras en C# sobre Unity
50
1.5. Público objetivo
El juego va destinado sobre todo a jugadores casuales, pero también a jugadores
regulares. Busca ser jugable en breves espacios de tiempo.
1.6. Plataformas
Se lanzará para los móviles Android, pero no se descarta lanzarlo en más
plataformas, como iOS o Windows Phone.
2.1.2. Enemigos
Los enemigos son muy variados, en aspecto y en atributos. Son los rivales del
héroe, y aparecen aleatoriamente por el mapa (siempre fuera de la zona segura,
la ciudad). Su objetivo es eliminar al héroe. Entre ellos también contamos a los
minijefes y jefes, que son enemigos especiales más fuertes que los enemigos
normales.
51
Desarrollo de un videojuego de aventuras en C# sobre Unity
2.1.3. Aliados
Son los habitantes de Lonetown y gente raptada que el héroe debe rescatar.
Hablarán con el héroe, ambientando la historia y dando pistas al jugador.
También pedirán la ayuda del héroe, dándole misiones a cambio de una
recompensa. Las misiones serán configuradas mediante un fichero XML, así
como los diálogos de cada personaje.
2.1.4. Neutrales
El robot de la tienda es el único personaje neutral. Su única función es la de
comerciar con el jugador, comprando y vendiendo objetos. Algunos de los
objetos requerirán piezas concretas para ser completados y funcionales,
evitando así que el jugador los use hasta que el diseñador lo desee.
52
2.2.2. Armaduras
Reducen el daño que recibe el héroe. Al igual que las armas, sólo se puede llevar
una a la vez, se cambia en el baúl del pueblo y se pueden crear mediante piezas
o comprar en el pueblo.
53
Desarrollo de un videojuego de aventuras en C# sobre Unity
Mientras no se derroten todos los minijefes, el jefe fina del nivel será accesible
pero resultará imposible de derrotar, pues derrotará al héroe al primer golpe, y
éste no causará ningún daño al enemigo.
54
2.4. Diseño de la interfaz
2.4.1. Menús (fuera del juego)
55
Desarrollo de un videojuego de aventuras en C# sobre Unity
2.4.3. Juego
2.4.4. Batalla
56
2.4.5. Diálogos
3. Recursos
3.1. Audios
Menú: http://www.looperman.com/loops/detail/75568
Combate: http://www.looperman.com/loops/detail/74107
Explorando: http://www.looperman.com/loops/detail/73606
3.2. Imágenes
Enemigos: http://opengameart.org/content/bosses-and-monsters-
spritesheets-ars-notoria
Héroe y tileset del mapa: http://opengameart.org/content/blowhard-2-
blow-harder
57