Читать книгу: «Unity 3D»
UNITY 3D
UNITY 3D
Marc Lidon

Unity 3D
© 2019 Marc Lidon
Primera edición, 2019
© 2019 MARCOMBO, S.A.
www.marcombo.com
Diseño de la cubierta: ArteMio
Maquetación: ArteMio
Revisor técnico: Pablo Martínez
Correctora: Laura Seoane
Directora de producción: M.ª Rosa Castillo
«Cualquier forma de reproducción, distribución, comunicación pública o transformación de esta obra sólo puede ser realizada con la autorización de sus titulares, salvo excepción prevista por la ley. Diríjase a CEDRO (Centro Español de Derechos Reprográficos, www.cedro.org) si necesita fotocopiar o escanear algún fragmento de esta obra».
ISBN: 978-84-267-2682-7
D.L.: B-25488-2018
Impreso en Printek
Printed in Spain
Quiero agradecerle a Jaume Castells la dedicación y el esfuerzo
por enseñarme el camino de la programación:
“Un buen maestro marca la diferencia” y también a Enrique Rendón, porque en toda buena aventura necesitas un buen compañero.
Contenido
Introducción a Unity
1. Introducción
2. ¿Qué es Unity?
3. Descarga e instalación de Unity
4. Proyectos 2D y 3D
5. Guardar el proyecto y la escena
Interfaz de Unity
1. Importación de Assets
2. Ventana Proyectos (Project)
3. Ventana Escena (Scene View)
4. Ventana Juego (Game View)
5. Ventana Jerarquía (Hierarchy window)
6. Ventana Inspector y creación de un GameObject
Editor de terrenos
1. Crear un terreno
2. Esculpir la superficie
3. Pintar el terreno
4. Poner vegetación
5. Poner agua en el terreno
6. Crear una zona de viento (windzone)
7. Editar árboles
Creación de un escenario modular
1. Importar los modelos
2. Modelos
3. Materiales y texturas
4. Parámetros básicos de los materiales
5. Colliders y Rigid Bodies
6. Model vs Prefabs
7. Montar un escenario simple
8. Importar Standard Assets y probar el escenario
Introducción básica de C# con Unity
1. Introducción
2. Crear y manipular variables
3. Trabajar con operadores aritméticos
4. Operadores lógicos y de comparación
5. Crear declaraciones lógicas con if - else
6. Crear declaraciones con switch
7. Trabajar con loops
8. Crear y llamar funciones
9. Entender qué son los Arrays
10. Mi primera clase
Programación orientada a objetos
1. Introducción
2. Clase GameObject
3. Acceder a los componentes
4. Entender las transformaciones
5. Vector3
6. Mover objetos
7. Rotar objetos
8. Escalar objetos
Creación de un Player en C#
1. Introducción
2. Character Controller
3. Movimientos del Character Contoller
4. Los Inputs
5. Mover y rotar nuestro Character Controller
6. Saltar obstáculos
7. Rigidbody
8. Mover un Rigidbody
9. Controlar el movimiento de un Rigidbody
10. Añadir un salto al Rigidbody
11. Seguimiento simple de nuestra cámara
12. Destruir objetos con colisiones
13. Tele-transportación con Triggers
14. Proyecto final
Raycast y Decals
1. Introducción
2. Abrir puertas con triggers
3. Raycast
4. Cómo obtener información con RaycastHit
5. Comunicación con SendMessage
6. Decals
7. Instanciar los Decals con Raycast
8. Rotación de nuestros Decals
9. Selección de objetos para disparar
10. Crear un Array de Decals
11. Emparentar los Decals
12. Destruir las Cajas
UI (Interfaz de Usuario)
1. Introducción
2. Entendiendo el Canvas (lienzo)
3. Entendiendo el Rect Transform
4. Image
5. Image Raw
6. Text
7. Button
8. Slider
9. Creación de una mirilla
10. Creación de un contador de coins
11. Creación de una barra de vida
12. Hacer daño a nuestro FPSController
13. Cómo curar a nuestro FPSController
14. Cómo limitar el número de munición
15. Pantalla de fallecimiento
Animación
1. Animación en Unity
2. El flujo de trabajo
3. Animation Clips
4. Ventana Animation
5. Animation Controller
6. Máquina de estados
7. Proyecto de un soldado
Navigation y Pathfinding
1. Vista general del sistema de navegación en Unity
2. Cómo funciona el sistema de navegación
3. Construir un NavMesh
4. Crear un NavMesh Agent
5. Crear un NavMesh Obstacle
6. Crear un Off-mesh Link
7. Proyectos de Navigation
Iluminación
1. Introducción
2. Iluminación
3. Apagar las luces
4. Tipos de luces
5. Propiedades de las luces
6. Iluminación directa e indirecta
7. Iluminación Baked
8. Iluminación Mixed
9. Práctica general
10. Ponte a prueba
Las partículas
1. Introducción
2. Sistema de partículas
3. Creación de un sistema de partículas
4. Editar las propiedades de las partículas
Menús y sonido
1. Introducción
2. Vista general de sonido
3. Empezar con el proyecto
4. Creación de nuestro Player
5. Crear proyectiles para nuestro player
6. Crear un enemigo
7. Colisiones
8. Explosiones
9. Añadir sistema de puntos y vidas
10. Escena principal y GameOver

1. Introducción
Primero te doy la bienvenida y las gracias por adquirir esta obra, que pretende documentar de una forma práctica todos los módulos básicos de Unity con todo lo que conlleva aprender un programa de este tipo.
Para empezar con buen pie he creído conveniente hacer una introducción desde cero y crear una base con la que trabajar. Cuando hablo de base me refiero a que el verdadero potencial de Unity reside en la facilidad con la que podemos crear interactividad entre objetos mediante la programación. Entiendo que a muchos les dé miedo la palabra programación por la misma razón que a mí en mis comienzos y es el desconocimiento. Esta es la primera de las razones que nos frenan a la hora de crear grandes proyectos, en todo caso no prometo que después de terminar el libro te conviertas en un súper programador, seamos humildes y tengamos los pies en el suelo, la respuesta es no, pero sí que vas a adquirir conocimientos y habilidades que te permitirán entender cómo se realizan juegos en Unity como empezar a leer código y, lo más importante, a utilizar Unity para crear tus propios proyectos.
2. ¿Qué es Unity?
Unity es un motor de videojuegos que se ha hecho muy popular en los últimos años. En realidad un motor de videojuegos es un conjunto de herramientas que nos facilitan el cálculo de formas geométricas y comportamientos físicos que se utilizan en los videojuegos. Estas herramientas están diseñadas para agilizar el proceso de creación de contenido del juego y no para la resolución de problemas informáticos.
Una de las características que hacen de este motor un referente en la industria de videojuegos es que nos permite la importación de muchos formatos 3D como 3ds, Cinema4D, Blender, FBX y también importar recursos de tipo gráfico, visual y de audio, todo ello posteriormente puede ser optimizado por Unity.
Unity permite construir juegos mediante su editor y un lenguaje de programación, que permite al usuario mediante scripts crear interacción. El usuario puede escoger entre Java Script, C# como lenguajes de programación y podrá consultar en la documentación de las API que proporciona Unity. En esta obra nos centraremos en el lenguaje C#-
Los juegos en Unity se crean mediante escenas que representaran un nuevo nivel o un lugar distinto dentro del juego. Las escenas se crean con el editor de terrenos de Unity o importando modelos propios.
Si no sabes modelar en 3d no te preocupes porque este libro viene acompañado de material adicional para que puedas realizar los proyectos. En el caso de que quieras realizar algún proyecto distinto puede descargar del Asset Store de Unity recursos, en donde encontraras material gratuito y de pago.
3. Descarga e instalación de Unity
Para empezar a trabajar con Unity te recomiendo que visites su página web https://store.unity.com/es/ y descargues la última versión que tengan en el caso de que no hayas instalado el programa.
Dispones de varas opciones de descarga, para seguir los proyectos del libro puedes descargar la versión gratuita. Esta versión gratuita tiene las herramientas necesarias para aprender a utilizar el programa.

Fig. 1.1
Una vez tengas descargado el paquete instala Unity haciendo clic en el instalador. Un aspecto que te recomiendo es el de no instalar todas las opciones que vienen por defecto porque alguna no las vamos a necesitar y van a ocupar un espacio valioso en su disco duro.

Fig. 1.2

Fig. 1.3

Fig. 1.4
4. Proyectos 2D y 3D
Una vez instalado el programa en tu ordenador, arrancaremos el programa haciendo doble clic en el icono de Unity del escritorio.
Al arrancar el programa se nos abrirá una ventana que nos da la bienvenida y nos pregunta si queremos trabajar offline (sin conexión) o accediendo con una cuenta de Unity.

Fig. 1.5
Si pulsamos la opción Work offline se nos muestra la siguiente ventana que nos permite abrir o crear un nuevo proyecto. A continuación voy a resumir que opciones tenemos en esta ventana.

Fig. 1.6
•La opción 1: para crear un nuevo proyecto.
•La opción 2: para abrir un proyecto que ya tengamos creado. Si te fijas en la parte de abajo veras dos flechas que te indican un menú en donde se muestran los proyectos recientes que tengamos creados. La opción On Disk muestra los proyectos guardados en el ordenador y la opción In the Cloud muestra los proyectos que tengamos creados en la nube.
•La opción 3: te volverá a mostrar la ventana de acceso a tu cuenta Unity. En el caso de que accedas con una cuenta la ventana te mostrara un icono en la parte superior que viene por defecto o tu avatar personal.

Fig. 1.7
Después de explicar todo lo anterior ya podemos crear un nuevo proyecto, para ello pulsa en el botón New que muestra la primera flecha de la imagen anterior. Se nos aparecerá otra ventana que permite, ahora sí, crear y guardar nuestro proyecto.

Fig. 1.8
•Opción 1: en este cuadro debemos ponerle el nombre a nuestro proyecto, por ejemplo “Mi_primer_proyecto”.
•Opción 2: en este cuadro debemos ponerle la ubicación donde queremos que se guarde.
•Opción 3: nos permite crear un proyecto de dos tipos 3D o 2D, en realidad se puede trabajar igual con uno que con el otro. Te recomiendo que selecciones la opción 3D para empezar. También verás que al lado hay un botón que sirve para añadir al proyecto paquetes de Assets que de momento no vamos a utilizar pero que veremos más adelante.
Una vez has realizado las acciones anteriores puedes pulsar el botón Create Project .
5. Guardar el proyecto y la escena
Bien, ya has creado tu primer proyecto y ahora vas a identificar algunos elementos de la interfaz para aprender a trabajar y organizar correctamente tus proyectos. Pero antes quiero que realices dos acciones muy importantes y que a veces caen en el olvido.

Fig. 1.9
En la parte superior de la interfaz hay un menú, accede a la opción File> Save Project; esta acción guardará tu proyecto y, a continuación, desde el mismo menú accede a la opción File> Save Scenes; se te abrirá una ventana de navegador que te permite guardar una escena con un nombre, escribe el nombre de Escena_1 y guárdalo en el lugar que te indica por defecto.
Vista previa de la interfaz
Verás que te aparece un elemento de la interfaz, no te preocupes porque ahora vamos a identificar los elementos principales de esta interfaz, que es la que viene por defecto.
En la siguiente imagen verás enumeradas varias zonas de la interfaz:

Fig. 1.10
1.Es la ventana escena, en donde construimos mediante objetos las escenas del juego. Verás que dentro de esta escena hay dos pestañas encima señaladas por flechas, son dos ventanas anidadas a este espacio, más adelante reorganizaremos la interfaz para recolocar estos elementos. Si haces clic encima de estas pestañas accederás al contenido de estas.
2.Esta es la ventana Jerarquía Hierarchy, esta ventana contiene todos los elementos de la escena actual. Actualmente en esta versión también organiza los objetos por escenas.
3.La ventana Project es una ventana que se divide a su vez en dos partes. La parte de la izquierda contiene una estructura jerárquica de carpetas, actualmente solo verás una carpeta que tiene el nombre de Assets, en donde podrás crear nuevas carpetas y poder organizar todos los archivos que necesites para el juego; escenas, modelos, texturas, materiales, scripts y audios, etc. En la parte derecha muestra el contenido de las carpetas.
4.La ventana Inspector es la ventana encargada de albergar todos los parámetros de los objetos que tengas seleccionados. También te va a permitir añadir nuevos parámetros y configurar algunos otros mediante scripts.
Configurar la interfaz
Cuando tenemos una disposición concreta de la interfaz nos referimos al layout. Ahora tiene una visión general de las ventanas que se muestran en el layout por defecto, pero Unity dispone de otros layouts pre configurados para facilitar el trabajo al usuario.
Para acceder a los distintos layouts accede al botón con nombre Default que encontrarás en la parte superior derecha de la interfaz.

Fig. 1.11
Al hacer clic en el botón se despliega un menú donde podemos seleccionar varias opciones. En este caso vamos a crear uno propio con ayuda de los que ya están creados, eso no quiere decir que más adelante prefieras otra configuración, esto simplemente es un ejercicio para que aprendas cómo puedes crear tu zona de trabajo.
Primero accedes al menú layout y seleccionas la opción Tall.

Fig. 1.12
Esta disposición me gusta y va a ser la disposición que se utilizará para todos los ejercicios del libro, con unas cuantas modificaciones que se explican a continuación.

Fig. 1.13
La imagen anterior tiene la interfaz distribuida con el layout Tall, ahora vamos a desanclar una ventana y anclarla en otro lugar de la interfaz, como por ejemplo la pestaña Game. Para realizar esta acción debes hacer clic con el botón izquierdo del ratón y, manteniéndolo pulsado, arrastrar hacia la zona baja de la interfaz. Verás que al llegar a la zona inferior se crea una especie de bloque en gris, es el momento de dejar de pulsar el botón izquierdo del ratón. Si lo has realizado correctamente acabas de recolocar la ventana Game debajo de la ventana Scene.

Fig. 1.14
Ahora para finalizar vas a añadir una ventana nueva que no está visible en la interfaz. Unity dispone de muchas herramientas y no todas se muestran en la interfaz, para realizar el ejercicio y añadir una ventana a la interfaz accede al menú principal que se encuentra en la parte superior de la interfaz y dirígete a Window>Console. A continuación aparecerá la ventana Console en forma de ventana flotante.
Realiza la misma acción que hiciste con la ventana Game y sitúa la ventana Console al lado de la ventana Game pero esta vez en forma de pestaña. Recuerda que solamente debes arrastrar la ventana manteniendo pulsado el botón izquierdo del ratón a la zona donde quieres colocarla, Unity se encarga de ensamblar la ventana al lugar. Si has realizado con éxito la acción debería quedarte una interfaz parecida a la siguiente imagen:

Fig. 1.15
Una vez tengas la interfaz adecuada a tus necesidades deberás guardar la configuración para las siguientes ocasiones. Para guardar el layout de la interfaz accede al menú de layouts y selecciona la opción Save Layout. A continuación Unity te pide que le pongas un nombre, por ejemplo: “Personal” y pulsa en Save para guardar la configuración.

Fig. 1.16
Felicidades, has creado tu primera interfaz personalizada. En capítulos más avanzados es posible que te interese crear otro tipo de layouts, pero ahora para empezar es suficiente.

1. Importación de Assets
La presente obra viene acompañada de material adicional con todo lo necesario para que puedas seguir los proyectos y aprender sin que pierdas detalle. Una de las primeras cosas que vas a tener que aprender es la importación de assets, que es el material necesario para seguir los proyectos de este libro.
En todo proyecto de Unity encontrarás una carpeta llamada Assets. Esta carpeta contiene varias carpetas en su interior en donde se guardan los objetos del juego, scripts, materiales, texturas, etc.
En este capitulo he creado un paquete de assets para que puedas trabajar con las distintas ventanas que se explican.
Para importar el paquete de assets de este capítulo primero ten localizado el material adicional del libro y la ubicación de la carpeta de este capítulo. Luego crea un proyecto nuevo y dale el nombre que quieras. Todos los proyectos serán en 3D siempre que no se diga lo contrario.
Accedemos al menú principal y nos dirigimos a Assets > Import Package > Custom Package y buscamos dentro del material del libro en el proyecto 2 el archivo Capitulo_2.unitypackage.

Fig. 2.1
Si todo es correcto, verás que en la ventana Projects te aparecen una serie de carpetas que comentaremos a continuación.
2. Ventana Proyectos (Project)
Esta ventana es un reflejo de las carpetas que constituyen tu proyecto y que se encuentran organizadas en tu ordenador, es decir, cada vez que creemos un archivo o una carpeta, esta se creará automáticamente en la carpeta de Assets de tu disco y viceversa.

Fig. 2.2
1.Este menú nos permite crear una gran variedad de elementos para el proyecto. Una muy utilizada es la creación de carpetas.
2.Esta sección tiene dos elementos: la carpeta Assets en donde añadirás nuevas carpetas para ordenar los elementos de tu proyecto y una sección de favoritos que te permite buscar por temática dentro de la carpeta misma.
3.Esta sección te muestra el contenido de las carpetas e irás cambiando según qué carpeta tengas seleccionada.
4.Este tirador permite cambiar el tamaño de los elementos que se muestran en la sección 3.
5.Este menú contiene una caja de textos para poder introducir el nombre del elemento que estás buscando. También puedes hacer búsquedas según el tipo de elemento, el label que tengan asignado o si se han guardado como favoritos.
6.En esta sección tenemos dos símbolos: un candado que bloquea esta ventana para que no se pueda modificar. El otro símbolo es un menú que podemos utilizar si queremos añadir una pestaña nueva con otro tipo de ventana.
Si has importado los assets anteriores verás que disponemos de tres carpetas: Escenas que contiene una escena llamada mi primera escena: la carpeta materiales que contiene 5 materiales; y una última carpeta que contiene una textura.

Fig. 2.3
Ahora vamos a crear una carpeta nueva que la vamos a llamar Prefabs primero asegúrate de que tienes seleccionada la carpeta Assets y luego, accediendo al menú Create > Folder. Seguidamente aparecerá una carpeta nueva a la que debes ponerle un nombre. Para borrar la carpeta simplemente selecciona la carpeta, haz clic con el botón derecho del ratón y seleccionar la opción Delete.

Fig. 2.4
Ahora para hablar de la siguiente ventana primero vamos a acceder a la carpeta Escenas y hacemos doble clic con el botón izquierdo encima de la escena con nombre Primera escena. Se abrirá una escena con varios objetos en la ventana View.
3. Ventana Escena (Scene View)
La ventana escena, o también podemos llamarla vista escena, es la parte de la interfaz en la que interactuaremos con el mundo que estamos creando. Esta ventana la utilizaremos para crear nuestras escenas para seleccionar y posicionar personajes, cámaras, luces y todos los demás tipos de objetos de nuestro juego. Poder seleccionar, manipular y modificar objetos en la vista de escena son algunas de las habilidades básicas que vas a aprender para comenzar a trabajar en Unity.

Fig. 2.5
Voy a mostrarte una imagen con todos los objetos básicos que podemos encontrarnos en una escena para que puedas identificarlos cuando los nombre.

Fig. 2.6
Primero vamos a aprender como navegar por el espacio tridimensional. Si haces clic encima del botón de navegación que se encuentra representado por una mano y luego posicionas el cursor encima de la ventana pulsando con el botón izquierdo del ratón podrá desplazar la vista de derecha a izquierda. Esta herramienta tiene tres estados:
1.
Mover: haciendo clic con el botón izquierdo y arrastrando encima del visor
2.
Orbitar: pulsando Alt+ botón izquierdo del ratón podrá orbitar alrededor del espacio 3D.
3.
Zoom: pulsando Alt + botón derecho del ratón podrá acercarse o alejarse de la escena. Si dispones de una rueda en el ratón también puede hacerla girar para hacer zoom. En el caso de Mac y Linux Comando (Control) + Shift y el botón derecho del ratón.
En la parte superior derecha de la ventana nos encontramos con un Gizmo. El gizmo nos muestra la dirección en que se encuentra nuestra cámara visor escena. También podemos interactuar con el gizmo. Este objeto te permite visualizar en todos los ejes de coordenadas y también permite ver en dos modos; perspectiva y ortográfica. Si pulsas en el cuadro interior del gizmo, representado en las siguientes imágenes con un color amarillo, podrá cambiar la vista de perspectiva a ortográfica.

Fig. 2.7
Si pulsas en los conos de colores la vista te mostrará en modo 2d la proyección del eje que haya seleccionado. Por ejemplo, si pulsad en el cono rojo este representa el eje X y te mostrará la vista desde este punto como se muestra en la siguiente imagen. El color verde representa el eje Y y el color azul representa el eje Z.

Fig. 2.8
Otro elemento que debes conocer es el menú de escena. El primer menú desplegable te muestra distintos modos de representar la escena dividida en sectores. Te recomiendo que hagas la siguiente prueba: accede al menú Shaded y escoge la opción Shaded Wireframe; la escena se representará mostrando una vista de alambre dibujada encima del material como se muestra en la siguiente imagen.

Fig. 2.9
Al lado del menú anterior dispones de una serie de botones que activan y desactivan opciones de la ventana escena. El 2D activa o desactiva esta vista, el botón con el símbolo del sol hace referencia a las luces de la escena, el símbolo del altavoz para el sonido y el botón con el símbolo de la foto alberga un submenú donde puedes marcar o desmarcar una serie de elementos que se desactivan o activan cuando pulsas este icono.

Fig. 2.10
Para finalizar este menú dispones de otra opción con el nombre gizmos que también te permite activar o desactivar elementos de la escena. Al lado de esta opción dispones de un buscador, que puede resultarte muy útil cuando trabajes con escenas muy grandes, con múltiples objetos.

Fig. 2.11
4. Ventana Juego (Game View)
Esta ventana es donde podemos ver el resultado de nuestra escena. Es donde se muestra la compilación de todos los objetos, comportamientos, iluminación y todo ello renderizado desde la cámara que tengas dentro de la escena.

Fig. 2.12
Barra de herramientas del Game View
Tenemos varias opciones para controlar cómo se muestra la imagen final de nuestra escena desde el visor Game. A continuación te detallo algunos aspectos que debes tener en cuenta.

Fig. 2.13
Display: contiene un menú desplegable para escoger la vista de la cámara que contiene la escena, por defecto está configurado para el Display 1.
Free Aspect: disponemos de una serie de valores predefinidos para probar cómo se vería nuestro juego en distintos formatos.
Scale: es un tirado que nos permite hacer zoom en la pantalla de juego para ver con más detalle nuestro juego o ver en modo global como se ve desde lejos.
Maximize on Play: al tener activada esta opción, cuando ejecutemos el juego en Modo Play la ventana Game se maximizara para que juegue en pantalla completa.
Mute audio: si activamos esta opción silenciaremos cualquier audio que haya dentro del juego cuando entremos en modo Play.
Stats: este botón activa o desactiva la ventana de estadísticas. Esta ventana nos ofrece información del renderizado gráfico y audio mientras esta en modo Play.
Gizmos: este botón activa o desactiva la visibilidad de cierto tipo de gizmos o iconos que veríamos en la ventana escena.
Play Mode
Estos botones de la barra de herramientas nos sirven para controlar el modo de reproducción del editor y ver cómo se reproduce el juego en la ventana Game. Un aspecto muy importante a tener en cuenta cuando trabajamos con este visor es que en modo de reproducción, los cambios que realicemos serán temporales es decir cuando paremos la reproducción de nuestro juego, todos los cambios que hayamos realizado se restablecerán a como estaban antes de entrar en modo de reproducción. La interfaz de usuario del editor se oscurece para advertirte de que estas en modo reproducción.

Fig. 2.14
5. Ventana Jerarquía (Hierarchy window)
La ventana Jerarquía contiene una lista de todos los GameObject (objetos,luces,cámaras) que encontramos en nuestra escena. Cuando agregamos un objeto a la escena este aparecerá en la lista y cuando eliminemos un objeto este también desaparecerá de esta lista. La lista se crea en el orden que vamos añadiendo o creando objetos. Puedes ver en la escena que tenemos en el proyecto como están organizados los objetos.

Fig. 2.15
En esta ventana también podemos efectuar varias acciones. Podemos cambiar el orden de nuestros objetos de la lista. Para cambiar el orden debemos seleccionar un objeto de la lista por ejemplo el ultimo elemento que es Cylinder y arrastrarlo hacia arriba hasta el tercer lugar que quede entre Directional Light y Plane.

Fig. 2.16
Otra acción que podemos hacer es emparentar objetos. Para que quede más claro vamos a coger dos objetos, la esfera y el cubo. En este ejemplo vamos a hacer que la esfera sea el hijo y el cubo el padre, esto quiere decir que cuando movamos el cubo la esfera también se moverá. Selecciona de la lista la esfera y arrastrarla encima de Cubo. Automáticamente se creará en cubo un subobjeto que es esfera.

Fig. 2.17
Un objeto padre puede tener varios hijos, y a su vez los hijos pueden ser padres y tener hijos como te muestro a continuación

Fig. 2.18
En la imagen anterior puedes ver cómo el objeto Cube tiene como hijos a Plane Cylinder y Sphere, y a su vez Sphere es padre de Capsule.
También podemos cambiar el nombre de los objetos primero un clic para seleccionar y luego otro clic encima del nombre del objeto, este se convertirá en una caja de textos donde puedes escribir el nombre.
6. Ventana Inspector y creación de un GameObject
En realidad todo lo que contiene una escena son GameObjects. Todos estos GameObjects disponen de características distintas, y por ese motivo voy a mostrarte cómo se crean, cómo se manipulan y cómo puedes ver sus características.
Para crear un GameObject puedes hacerlo de muchas formas distintas una de ellas es en el menú principal acceder a GameObject>3D Object> Cube, se creará un objeto llamado Cube que podrás ver en la ventana Hierarchy o Jerarquía.

Fig. 2.19
En las imágenes anteriores he decidido utilizar un cubo solo y no la escena completa que tenemos para que se entienda mejor, si lo deseas puedes seleccionar el cubo que tienes de la escena y seguir las explicaciones. Si seleccionas el GameObject Cube en la ventana Hierarchy, veras que en la ventana inspector aparecen las propiedades de este objeto. A continuación voy a explicarle las características de este GameObject.

Fig. 2.20
Esta ventana tiene una parte superior y a continuación en su parte inferior se divide en paneles o componentes que se pueden colapsar mediante una flecha en la parte superior izquierda.
En la parte superior de la ventana Inspector puedes realizar las siguientes acciones:
El primer elemento es un cubo de colores que en realidad es una herramienta que te permite asignar un icono al objeto para diferenciarlo en una escena del resto de objetos. Por ejemplo en una escena muy grande poder encontrar al jugador.

Fig. 2.21
Al lado del selector de iconos dispones de una caja selectora que desactiva el objeto cuando la de seleccionamos y activa el objeto cuando está seleccionada. A su lado puedes cambiar el nombre al objeto, en este ejemplo por defecto llamado Cube.

Fig. 2.22
La opción Static hace referencia a si un objeto es estático o no es estático, esta característica se utiliza según el tipo de iluminación utilicemos y qué función va a realizar este objeto en la escena. En estos momentos déjalo desactivado.

Fig. 2.23
Para terminar esta sección tenemos dos menús el Tag (etiqueta) y el Layer (capa). Estos menús te permiten poner etiquetas a los objetos y determinan a qué capas pertenecen. Son herramientas muy útiles en programación cuando queremos llamar a un objeto en concreto.

Fig. 2.24
El siguiente componente es el Transform y te permite manipular el objeto en el espacio 3D. Debes tener en cuenta que los ejes de coordenadas son los que están representados por colores en el guizmo de la ventana escena.

Fig. 2.25
Esta característica te ayudará a identificar hacia dónde quiere realizar la transformación. Si realizas la prueba y cambias de valores los siguientes parámetros verás que el objeto Cube cambia de posición (position), de rotación (rotation) y de tamaño (scale).

Fig. 2.26
Seguramente que mover objetos en una escena de este modo puede ser una tarea muy complicada. Por ese mismo motivo dispones de una serie de herramientas que no se han explicado anteriormente porque tiene más sentido verlas en este contexto.
En la ventana escena dispone de 3 botones para realizar estas mismas transformaciones en un objeto de una forma más intuitiva.

Fig. 2.27
Estas acciones puedes activarlas seleccionando el objeto y pulsando la tecla W para mover el objeto tecla E para rotarlo y tecla R para escalarlo. Para realizar una acción de transformación seleccionas uno de los ejes y pulsando y, manteniendo pulsado el botón izquierdo del ratón, arrástralo para poder desplazar, rotar o escalar el objeto.

Fig. 2.28
En la imagen anterior verás el resto de componentes del GameObject:
1.El componente Mesh es el encargado de darle una malla al objeto.
2.El componente Collider es una caja que delimita mediante cálculos físicos que superficie del objeto impactará con los otros objetos. Este parámetro se explica con mayor detalle en ejemplos posteriores.
3.El componente Mesh Renderer es un conjunto de parámetros que permiten que el objeto pueda ser renderizado por Unity.
4.Los GameObjects por defecto como este se les aplica un material por defecto que puede ser configurado posteriormente.
Ahora que has visto los distintos componentes que tiene un GameObject vas a crear uno totalmente de 0.
Primero en la ventana Hierarchy (Jerarquía) en la opción Create selecciona la opción Create Empty. Te aparecerá el nombre de GameObject en la ventana Jerarquía y en el inspector también tendrás el componente Transform pero en la ventana escena no tendrás ningún objeto. Eso se debe a que todavía no le has asignado los componentes que se te han mostrado anteriormente y que son necesarios para tener un GameObject en condiciones mínimas.

Fig. 2.29
Antes de añadir los componentes le ponemos un nombre en la caja de textos superior.

Fig. 2.30
Para añadir los componentes que necesitamos pulsamos en el botón Add Component. Se te abrirá un menú con muchas opciones, selecciona la opción Mesh>Mesh Filter

Fig. 2.31
Este componente te permite seleccionar que tipo de superficie tendrá el GameObject, para seleccionar el tipo de superficie pulsa en el punto que se encuentra al lado de la caja de textos y en el menú que aparece selecciona el tipo de superficie como se muestra en la siguiente imagen.

Fig. 2.32
El siguiente paso consiste en que el GameObject pueda ser renderizado por Unity, vuelve a pulsar el botón de Add Component>Mesh>Mesh Renderer. Verás que en la ventana aparece el objeto pero tiene un color rosado, esto sucede porque no tiene ningún material aplicado. Para proporcionarle un Material por defecto accede desde las opciones del componente Mesh Renderer>Materials que puedes desplegar mediante la flecha que tienes al lado haciendo clic encima de ella y se desplegaran las opciones de esta sección.
Para seleccionar el material pulsa en el punto al lado de la caja de texto de Element 0. Se te aparecerá una ventana donde puedes seleccionar varios materiales, escoge uno.

Fig. 2.33
Para finalizar todo el proceso de creación de un GameObject debes añadir el collider accediendo a Add Component>Physics>Capsule Collider. En la siguiente imagen se muestra el proceso, en este caso selecciona la opción que tiene la forma de cápsula, por comodidad, pero eso no quiere decir que no pueda poner ningún otro tipo, puedes experimentar todo lo que desees.

Fig. 2.34
En este primer capítulo no quiero entrar en mucho detalle en las opciones porque es mucho contenido para asimilar sobre todo si empiezas desde cero. Para finalizar este capítulo de introducción voy a proponerte un proyecto final en donde vas a poner en práctica todo lo que has visto en los distintos ejercicios.
•Crear un proyecto nuevo.
•Importar los assets del capitulo
•Guardar el proyecto y la escena.
•Crear GameObjects desde cero: 1 cubes, 1 esferas, 1 plano
•Poner nombre a los GameObjects.
•Mover, rotar y escalar GameObjects.
•Poner materiales básicos a los GameObjects.
Cuando hayas terminado con esta actividad pasa al siguiente capítulo.

Editor de terrenos
El editor de terrenos nos permite crear terrenos exteriores de una forma muy sencilla y con múltiples herramientas para darle color y textura. Para poder seguir el capítulo deberás crear un proyecto 3D e importar los assets que pertenecen a este capítulo.
Los terrenos son un trabajo muy complejo que conlleva muchas horas de dedicación, importando assets y colocándolos en el lugar que les corresponde. En este capítulo vas a aprender cómo crear un escenario exterior, pintar con texturas, poner vegetación, crear una zona de viento y cómo puedes crear tus propios árboles con el editor de arboles.

Fig. 3.1
1. Crear un terreno
Para crear un terreno nos dirigimos a la barra de herramientas principal y accedemos a GameObject > 3D Object > Terrain. Verás que los terrenos consumen bastantes recursos del sistema y si no disponemos de un PC potente, notarás como se ralentiza un poco todo.

Fig. 3.2
Antes de empezar a trabajar en nuestro terreno vamos a configurar cómo queremos el terreno. Para ello nos dirigimos al panel inspector y accedemos al apartado Terrain y en el menú seleccionamos la última opción, como se muestra en la siguiente imagen:

Fig. 3.3
La configuración se divide en apartados que a continuación explico en detalle.

Fig. 3.4
| Base Terrain | |
| Draw | Activa o desactiva la representación del terreno. |
| Pixel Error | Es la precisión del mapeado entre los mapas del terreno y el terreno generado; los valores más altos indican una exactitud más baja pero una sobrecarga de representación más baja. |
| Base Map Distance | La distancia máxima a la que las texturas del terreno se mostrarán en la resolución completa. Más allá de esta distancia, una imagen compuesta de menor resolución se utilizará para la eficiencia. |
| Cast Shadow: | Activa o desactiva las sombras del terreno. |
| Material | Es el material utilizado para representar el terreno. Esto afectará a cómo se interpretan los canales de color de una textura de terreno. |
| •Built in Standard. Este es el material PBR (Phisical-Based Rendering) introducido en Unity 5.0. Para cada capa splat, puede usar una textura para albedo y suavidad, una textura para normal y un valor escalar para ajustar el metal.•Built in Legacy Diffuse. Este es el material heredado incorporado en el terreno de Unity 4.x y anteriores. Utiliza el modelo de iluminación Lambert (termino difuso solamente) y tiene soporte de mapa normal opcional.•Built in Legacy Specular. Este material incorporado utiliza BlinnPhong (término difuso y especular) como modelo de iluminación y tiene soporte de mapa normal opcional. Puedes especificar el color especular general y brillo para el terreno.•Custom. Utiliza un material personalizado de tu elección para representar el terreno. Este material debe usar un sombreado que esté especializado para renderizar el terreno (por ejemplo, debes manejar la textura que se aplique apropiadamente). | |
| Reflection Probes | Cómo se utilizan las sondas de reflexión en el terreno. Solo es efectivo cuando se utiliza un material estándar incorporado o un material personalizado que admita la representación con reflexión. |
| •Off. Las sondas de reflexión están desactivadas, skybox se utilizará para la reflexión.•Blend Probes. Las sondas de reflexión están habilitadas. La mezcla se produce solo entre las sondas. La reflexión predeterminada se utilizará si no hay sondas de reflexión cerca, pero no se producirá ninguna mezcla entre la reflexión por defecto y la sonda.•Blend Probes And Skybox. Las sondas de reflexión están habilitadas. La mezcla se produce entre las sondas o las sondas y la reflexión por defecto.•Simple. Las sondas de reflexión están habilitadas, pero no se producirá ninguna mezcla entre sondas cuando hay dos volúmenes superpuestos. | |
| Thickness | Qué cantidad de volumen de colisión del terreno debe extenderse a lo largo del eje Y negativo. Los objetos se consideran colisionados con el terreno desde la superficie hasta una profundidad igual al espesor. Esto ayuda a evitar que los objetos en movimiento de alta velocidad penetren en el terreno sin utilizar una gran cantidad de colliders continuos. |

Fig. 3.5
| Tree & Detail Objects | |
| Draw | Activa o desactiva la representación de árboles , hierba y detalles. |
| Detail Distance | La distancia (de la cámara) más allá de los detalles que serán eliminados. |
| Detail Density | El número de objetos de detalle / hierba en una unidad de área dada. El valor se puede establecer más bajo para reducir la sobrecarga de renderizado. |
| Tree Distance | La distancia (desde la cámara) más allá de los árboles que serán sacrificados. |
| Billboard Start | La distancia (desde la cámara) en la que los objetos del árbol 3D serán reemplazados por las imágenes de la cartelera. |
| Fade length | Distancia sobre la cual los arboles harán la transición entre objetos 3D y carteleras. |
| Max Mesh Trees | El número máximo de árboles visibles que se representarán como mallas 3D sólidas. Más allá de este límite, los árboles serán reemplazados por vallas publicitarias. |

Fig. 3.6
| Wind Settings for Grass | |
| Speed: | La velocidad del viento al soplar el césped. |
| Size: | El tamaño de las “ondulaciones” en las áreas cubiertas de hierba cuando el viento sopla sobre ellas. |
| Bending: | El grado en que los objetos de hierba están doblados por el viento. |
| Grass Tint: | Teñido general del color aplicado a los objetos de la hierba. |

Fig. 3.7
| Resolution | |
| Terrain Width | Tamaño del objeto de terreno en su eje X (en unidades unity). |
| Terrain Length | Tamaño del objeto de terreno en su eje Z (en unidades unity). |
| Terrain Height | Diferencia en la coordenada Y entre el valor de mapa de altura más bajo posible y el más alto (en unidades del mundo). |
| Heightmap Resolution | Resolución de píxeles del mapa de altura del terreno (debe ser una potencia de dos más uno, por ejemplo, 513 = 512 1). |
| Detail Resolution | Resolución del mapa que determina los parches separados de detalles / hierba. Una resolución más alta ofrece parches más pequeños y más detallados. |
| Detail Resolution per Patch: | Longitud / ancho del cuadrado de parches renderizado con una sola llamada de dibujo. |
| Control Texture Resolution: | Resolución del “splatmap” que controla la mezcla de las diferentes texturas del terreno. |
| Base Texture Resolution: | Resolución de la textura compuesta utilizada en el terreno cuando se ve desde una distancia mayor que la distancia de base (véase más arriba). |
Heightmap Importar/Exportar
Los botones Importar y Exportar nos permiten establecer o guardar el mapa de altura del terreno en un archivo de imagen en el formato RAW que es una imagen en escala de grises. El formato RAW puede ser generado por herramientas de edición de terrenos de terceros (como Bryce) y también puede ser abierto, editado y guardado por Photoshop o Gimp. Esto permite la generación sofisticada y la edición de terrenos fuera de Unity.

Fig. 3.8
Explicada las propiedades de configuración, cambia el tamaño de tu terreno de forma que no te consuma muchos recursos. En el ejemplo que te muestro he puesto en el apartado de resolución los siguientes parámetros:
•Terrain Width= 100
•Terrain Length= 100
•Terrain Height = 50
Puedes poner el valor que te vaya mejor para crear tu terreno.
2. Esculpir la superficie
Vamos a ver cómo trabajar con la primera herramienta de las propiedades Terrain.

Fig. 3.9
La función es muy simple: tenemos una serie de pinceles (Brushes) con distintas formas que están representadas con una pequeña imagen. Estos pinceles tienen dos opciones para configurar (Settings).
•Brush Size: el tamaño, a mayor tamaño nuestros trazos serán más grandes.
•Opacity: la opacidad del pincel. A mayor opacidad más fuertes serán nuestros trazos.
Selecciona un pincel y configura el tamaño y la opacidad que quieras. Vamos a la ventana Scene y veremos que nuestro cursor se ha convertido en una sombra azulada con la forma de nuestro pincel.

Fig. 3.10
Tenemos dos acciones a realizar con esta opción. Para añadir terreno pulsamos con el Botón Izquierdo del ratón (BIR). Para quitar terreno pulsamos Botón Izquierdo del ratón manteniendo pulsada la tecla SHIFT (BIR+SHIFT).

Fig. 3.11
Esta última acción que hemos realizado (la de quitar terreno o hundir), no permite hundir más allá de la base del terreno. Esto sucede porque debemos decirle donde está el nivel 0, es decir tenemos que levantar el terreno a una cierta altura para poder rebajar zonas de nuestro terreno. Lo vemos en el siguiente apartado.
Paint Height
Esta es la segunda opción de la creación de terrenos. Verás que se le añade una opción de configuración el Height. Esta opción determina la posición en la que situaremos nuestro terreno y tiene mucho que ver con la configuración que hemos puesto al principio.

Fig. 3.12
Si recordamos en la configuración del terreno he puesto el valor en Height de 50 unidades, esto me permite crear una altura de montañas hasta 50 unidades. En el caso de que quiera crear cráteres o caudales de río tendré que posicionar el terreno por ejemplo a la mitad de la altura máxima. De esta manera ponemos 25 unidades en Height que será la posición base de nuestro terreno y para ejecutar la acción pulsamos Flatten.

Fig. 3.13
Ahora si volvemos a la herramienta de elevación de terreno y pulsamos Shift +BIR (Botón izquierdo ratón) verás como puedes hundir el terreno hasta 25 unidades. Esta segunda herramienta te permite aplanar el terreno a nivel 0 tanto en las elevaciones como en las hendiduras en el caso de que te hayas equivocado o no te guste el resultado.
Smooth Height
Como su nombre indica, esta opción permite suavizar los relieves del terreno. Contiene las mismas opciones que los pinceles anteriores y la configuración básica; tamaño y opacidad.

Fig. 3.14
En la siguiente imagen te muestro un mismo relieve: el de la izquierda es sin suavizar y el de la derecha aplicando la herramienta Smooth Height.

Fig. 3.15
3. Pintar el terreno
Paint Texture
Esta es la opción que nos permite pintar el terreno con texturas, pero en un principio no puede pintar porque no tiene ninguna textura asignada.

Fig. 3.16
Si miramos en sus opciones verás que tiene un botón llamado Edit Textures. Al hacer clic encima veremos un menú emergente que solamente nos permite seleccionar la opción Add texture, hacemos clic en esta opción.
Atención: Debes importar los assets del capítulo 3 para que puedas disponer del material necesario.
Se nos aparecerá un menú flotante que nos permite añadir texturas para pintar. El menú tiene dos recuadros, uno para la textura de color y el otro para la textura de relieve. Selecciona el primer recuadro, escoge una textura de hierba (GrassHilAlbedo) y pulsa en el botón Add.

Fig. 3.17
Por defecto Unity pinta todo el terreno con la primera textura. En el caso de que quisiéramos escalar la textura solamente debemos volver a las propiedades de terreno y acceder al menú Edit Texture > Edit Texture. Aparece otra vez el menú anterior y podemos variar los parámetros de la textura en X e Y cómo te muestro a continuación.

Fig. 3.18
Ahora vamos a añadir una textura de piedra para pintar las montañas. Pulsamos en las propiedades del terreno Edit Texture> Add texture y seleccionamos una textura que nos guste MudRockyAlbedo esta textura también tiene una textura de relieve (Normal Map) así que hacemos clic en el recuadro de al lado, seleccionamos MudRocky Normals y pulsamos en el botón Add. Ahora solo tenemos que seleccionar esta textura nueva, seleccionar el tipo de pincel y en la configuración de pinceles debemos tener en cuenta la opción Target strength. Esta opción nos permite regular la fuerza con la que pintamos, a mayor fuerza mejor se verá la textura que pintamos.

Fig. 3.19
Nota: si quieres tener un entorno más profesional debes intentar que las texturas se difuminen unas con otras, es decir utiliza los parámetros opacity y Target strength con conocimiento buscando el equilibrio en ambas.
4. Poner vegetación
Place Tree
Esta opción nos permite pintar árboles. En realidad los árboles son prefabs que se crearán cuando hagamos un trazo en nuestro terreno.

Fig. 3.20
Como en el caso de las texturas debemos hacer clic en la opción Edit Trees > Add Trees para añadir estos prefabs. Selecciona uno por ejemplo Palm_Desktop y confirma pulsando la opción Add.

Fig. 3.21
Atención: si has cargado los Assets del capítulo 3 tendrás algunos árboles para utilizar, si no lo has hecho todavía debes cargar este paquete para poder seguir la explicación.
Una vez tenemos un árbol seleccionado se nos aparecerán varias opciones, que nos permiten modificar la configuración de nuestro trazo en el terreno.
| Brush size | El tamaño que abarca nuestro pincel a la hora de crear árboles. |
| Tree Density | La cantidad máxima de árboles que creará en cada trazo. Este parámetro va muy relacionado al tamaño del pincel. |
| Tree Height | Este parámetro nos permite jugar entre una cantidad de valores que hacen referencia a la altura de los árboles. También tiene la opción Random, que al estar activo hace que la creación de nuestros arboles varíe con cada trazado. |
| Lock Width to Height: | Esta opción al estar activada, hace que los árboles tengan una proporción entre ancho y alto. |
| Tree Width | Esta opción por defecto esta desactivada. Se activa al desactivar la opción anterior Lock Width to Height, y nos permite crear árboles más delgados aleatoriamente según qué cantidades le configuremos. |
| Random Tree Rotation | Permite al estar activo que los árboles tomen una rotación aleatoria y de este modo dar un efecto mas realista. |

Fig. 3.22
En las opciones de configuración también tenemos un botón llamado Mass Place Trees; al pulsarlo se nos abre un menú en donde podemos poner un número de árboles para que Unity nos cree todos los árboles en el terreno aleatoriamente. Esta es una forma muy rápida de crear vegetación pero casi siempre crea árboles en zonas que no deseamos.

Fig. 3.23
Para borrar todos los árboles que abarca el pincel pulsar SHIFT +BIR. Para borrar los árboles individualmente pulsar CTRL+BIR.
Paint Details
Con esta opción podemos crear vegetación o detalles de otro tipo a partir de texturas con canal alfa o modelos y props como rocas para dar ambiente a nuestro escenario. El funcionamiento es el mismo que hasta ahora tenemos los pinceles y su configuración igual que los árboles.

Fig. 3.24
Para añadir una textura con canal alfa debes seleccionar Add Grass Texture; si deseas añadir un modelo debes seleccionar la opción Add Detail Mesh.

Fig. 3.25
En el menú que se aparece debes escoger en la primera opción para seleccionar la textura que desees; en este caso se ha seleccionado GrassFrond02Albedo. Si deseas cambiar el color o el tamaño de la textura puedes jugar con los parámetros de debajo.
5. Poner agua en el terreno
Unity dispone dentro de la carpeta Environment de una carpeta llamada Water y Water Basic en donde podemos utilizar sus prefabs para poner aguas muy realistas en nuestros terrenos.

Fig. 3.26
El prefab es un gameObject con características ya predefinidas, para utilizar este prefab desde la carpeta Project selecciona el prefab WaterBasic o el que desees y arrástralo hacia la ventana escena. Ahora debes escalar y posicionar el prefab desde la ventana Inspector, para que tenga el tamaño y la posición adecuados.

Fig. 3.27
6. Crear una zona de viento (windzone)
Las zonas de viento añaden realismo a los árboles haciendo que estos agiten sus ramas y hojas como si realmente hiciera viento.
Podemos crear una zona de viento accediendo al menú principal en GameObject > 3D Object > Wind Zone

Fig. 3.28
| Propiedades de WindZone | |
| Mode | Esta opción es la que te permite seleccionar entre un wind zone esférico o direccional. |
| Spherical. La zona del viento sólo tiene un efecto dentro del radio de la esfera, y va perdiendo fuerza desde el centro hacia el borde.Directional. La zona de viento es direccional y afecta a toda la escena en una dirección. | |
| Radius: | Radio de la zona de viento esférica (solo activo si el modo se establece en Esférico). |
| Main: | La fuerza primaria del viento. Produce una presión de viento que cambia suavemente. |
| Turbulence: | La fuerza del viento de la turbulencia. Produce una presión de viento que cambia rápidamente. |
| Pulse Magnitude: | Define cuánto el viento cambia con el tiempo. |
| Pulse Frequency: | Define la frecuencia de los cambios de viento. |
Consejo: para producir un viento general que cambia suavemente, cree una zona de viento direccional. Establece Main a 1.0 o menos, dependiendo de la potencia del viento, ajustar la turbulencia a 0.1, establece la magnitud de pulso en 1.0 o más y para finalizar establecer la frecuencia de pulso a 0.25.
7. Editar árboles
Unity dispone de una herramienta llamada Tree editor que permite al usuario crear cualquier tipo de árbol. Esta herramienta es especialmente útil para poder crear distintos tipos de bosques.
Para crear nuestro primer árbol debemos acceder en el menú de herramientas en GameObject > 3D Object > Tree.
Una vez creado veras que aparece el tronco de un árbol con un círculo de color amarillo. En el inspector aparece una serie de parámetros. Esta interfaz proporciona todas las herramientas para modelar y esculpir sus árboles. En la ventana de esta interfaz verás dos nodos que son: el nodo raíz del árbol y un único nodo de grupo de ramas, que llamaremos tronco del árbol. En la jerarquía de árbol, selecciona el grupo de rama, que actúa como el tronco de árbol.

Fig. 3.29

Fig. 3.30
El primer parámetro que vemos en el panel inspector es una ventana que contiene la estructura de nuestro árbol. En la parte inferior derecha veremos una serie de botones que nos permiten añadir elementos a nuestro árbol. Antes de empezar a trabajar con el debemos entender cómo funciona. El nodo que contiene el dibujo de un árbol es el nodo raíz y por tanto este es el nodo base donde se sustenta todos los demás elementos.

Fig. 3.31
El encabezado
Si hacemos clic en el nodo superior veremos que los parámetros inferiores cambian. Estos nuevos parámetros afectan solamente al nodo seleccionado, excepto al de raíz que afecta a todo el conjunto. El nodo con el icono de una rama es el nodo del tronco y a este nodo le añadiremos nuevas ramas que a su vez tendrán sub-ramas y estos últimos tendrán las hojas. Los nodos disponen de un icono principal que muestra el tipo de elemento que es, el número superior derecho es el número de ramas que existen en este nivel del árbol y la imagen del ojo nos permite activar o desactivar la visibilidad del objeto en la ventana escena.

Fig. 3.32
En la parte inferior derecha disponemos de una serie de herramientas para añadir nuevos nodos. De izquierda a derecha la primera herramienta añade grupos de hojas, estas se disponen en niveles igual que las ramas, pero a diferencia de las ramas, las hojas no pueden subdividirse en más niveles. La segunda herramienta añade grupos de ramas al nivel que tengamos seleccionado, es decir si tenemos seleccionado el nivel 1 (el tronco) iremos añadiendo ramas a este. La tercera herramienta duplica el nodo que tengamos seleccionado y la última herramienta elimina el grupo seleccionado.

Fig. 3.33
Editar grupos
Hemos visto cómo podemos crear grupos y ahora vamos a ver cómo podemos editarlos manualmente. Cuando seleccionamos una rama en la ventana de nodos, veras que en la ventana de escena aparece una curva y la recorre una serie de cubos. Estos cubos son puntos de control que podemos seleccionar y desplazar para dar una forma concreta a la rama.

Fig. 3.34
Estos puntos de control pueden ser de desplazamiento de rotación o también Unity nos da la posibilidad de dibujar la rama trazando una trayectoria.
Para seleccionar que el tipo de edición que queremos hacer disponemos de un menú que se encuentra debajo de la ventana de nodos con los siguientes botones:
Para la rotación los puntos de control tomaran la forma de un círculo y para crear un trazo simplemente debemos empezar a trazar una trayectoria encima de del punto de control en donde queremos que empiece.
Propiedades de los grupos de rama
Estas propiedades aparecen siempre que tengamos seleccionado el nodo del grupo de ramas y las propiedades solamente afectarán a ese grupo de ramas.
Distribution
Ajusta y distribuye las ramas en el grupo. Utiliza las curvas para ajustar la posición, la rotación y la escala. Las curvas son relativas a la rama madre o al área extendida en caso de un tronco.

Fig. 3.35
| Group Seed | La semilla para este grupo de ramas. Modifica el valor para variar la generación de ramas. |
| Frequency | Ajusta el número de ramas creadas para cada rama principal. |
| Distribution | La forma en que las ramas se distribuyen a lo largo de sus padres. |
| Growth Scale | Define la escala de nodos a lo largo del nodo padre. Utiliza la curva para ajustar y el deslizador para atenuar el efecto. |
| Growth Angle | Define el ángulo inicial de crecimiento con respecto al padre. Utiliza la curva para ajustar y el deslizador para atenuar el efecto. |
Geometry
Selecciona qué tipo de geometría se genera para este grupo y qué materiales se aplicarán. LOD Multiplicador te permite ajustar la calidad de este grupo en relación con la calidad LOD del árbol.

Fig. 3.36
| LOD Multiplier | Ajusta la calidad de este grupo en relación con la calidad LOD del árbol, de modo que sea de calidad superior o inferior al resto del árbol. |
| Geometry Mode | Tipo de geometría para este grupo de rama: Solo rama, Frondas de rama, Frondas solamente. |
| Branch Material | Primer material para las ramas. |
| Break Material | Material para cubrir las ramas rotas. |
Shape
Ajusta la forma y el crecimiento de las ramas. Utiliza las curvas para afinar la forma, todas las curvas son relativas a la propia rama.

Fig. 3.37
| Lenght | Ajusta la longitud de las ramas. |
| Relative Length | Determina si el radio de una rama está afectado por su longitud. |
| Radius | Ajusta el radio de las ramas, utiliza la curva para ajustar el radio a lo largo de la longitud de las ramas. |
| Cap Smoothing | Define la redondez de la tapa / punta de las ramas. Útil para cactus. |
| Growth | Ajusta el crecimiento de las ramas. |
| Crinkliness | Ajusta la forma torcida de las ramas, utiliza la curva para afinar. |
| Seek Sun | Utiliza la curva para ajustar cómo las ramas se doblan hacia arriba / hacia abajo y el deslizador para cambiar la escala. |
| Noise | Factor de ruido general |
| Noise Scale U | Escala del ruido alrededor de la rama, los valores más bajos darán un aspecto más vacilante, mientras que los valores más altos dan un aspecto más estocástico. |
| Noise ScaleV | Escala del ruido a lo largo de la rama, los valores más bajos darán un aspecto más vacilante, mientras que los valores más altos da un aspecto más estocástico. |
| Flare Radius | El radio de los puntos de luz, esto se añade al radio principal, por lo que un valor cero significa que no hay puntos brillantes. |
| Flare Height | Define hasta qué punto el tronco comienzan los puntos de luz. |
| Flare Noise | Define el ruido de los puntos de luz, los valores más bajos darán un aspecto más vacilante, mientras que los valores más altos darán un aspecto más estocástico. |
| Break Chance | Posibilidad de rotura de una rama, es decir, 0 = ninguna rama está rota, 0,5 = la mitad de las ramas están rotas, 1,0 = todas las ramas están rotas. |
| Break Location: | Esta gama define dónde se romperán las ramas. Relativo a la longitud de la rama. |
Las siguientes propiedades las encontrarás en las ramas hijas del tronco.
| Weld Length | Define qué tan arriba en la rama comienza la extensión de la unión. |
| Spread Top | Factor de propagación de la unión en la parte superior de la rama, en relación con su rama principal. Cero significa que no hay propagación. |
| Spread Bottom | Factor de ensanchamiento de la unión en la parte inferior de la rama, en relación con su rama principal. Cero significa que no hay propagación. |
Wind
Ajusta los parámetros utilizados para animar el conjunto de ramas. Las zonas de viento solo están activas en el modo de reproducción.

Fig. 3.38
| Main Wind | Efecto del viento primario. Esto crea un suave movimiento de balanceo y es el único parámetro necesario para las ramas primarias. |
| Main Turbulence | Turbulencia a lo largo del borde de las frondas. Útil para helechos, palmeras, etc. |
Propiedades de los grupos de hojas
Estas propiedades aparecen siempre que tengamos seleccionado el nodo del grupo de hojas. Los grupos de hojas generan la geometría del follaje. Ya sea de primitivas o de mallas creadas por el usuario.
Distribution
Ajusta el recuento y la colocación de las hojas en el grupo. Utiliza las curvas para ajustar la posición, la rotación y la escala. Las curvas son relativas a la rama madre.

Fig. 3.39
| Group Seed | El comienzo para este grupo de hojas. Modifica los valores para variar la generación del comienzo. |
| Frequency | Ajusta el número de hojas creadas para cada rama principal. |
| Distribution | Selecciona la forma en que las hojas se distribuyen a lo largo de su padre. |
| Twirl | Gira alrededor de la rama principal. |
| Growth Scale | Define la escala de nodos a lo largo del nodo padre. Utiliza la curva para ajustar y el deslizador para atenuar el efecto. |
| Growth Angle | Define el ángulo inicial de crecimiento en relación con el padre. Utiliza la curva para ajustar y el deslizador para atenuar el efecto. |
Geometry
Seleccione qué tipo de geometría se genera para este grupo de hojas y qué materiales se aplican. Si utiliza una malla personalizada, se utilizarán sus materiales.

Fig. 3.40
| Geometry Mode | El tipo de geometría creada. Puedes usar una malla personalizada, seleccionando la opción Malla, ideal para flores, frutas, etc. |
| Material | Material utilizado para las hojas. |
Shape
Ajusta la forma y el crecimiento de las hojas.

Fig. 3.41
| Size | El tipo de geometría creada. Puedes usar una malla personalizada, seleccionando la opción Malla, ideal para flores, frutas, etc. |
| Perpendicular Align | Ajusta si las hojas están alineadas perpendicularmente a la rama principal. |
| Horizontal Align | Ajusta si las hojas están alineadas horizontalmente. |
Wind
Ajusta los parámetros utilizados para animar el conjunto de hojas. Las zonas de viento solo están activas en el modo de reproducción.

Fig. 3.42
| Main Wind | Efecto del viento primario. Por lo general esto debe mantenerse como un valor bajo para evitar que las hojas floten lejos de la rama principal. |
| Main Turbulence | Efecto secundario de la turbulencia. Para las hojas esto se debe mantener generalmente con un valor bajo. |
| Edge Turbulence | Define la cantidad de turbulencia del viento que se produce a lo largo de los bordes de las hojas. |
Ejemplo de un árbol
Una vez hemos visto los parámetros principales crea un árbol del tipo que desees como el que te muestro a continuación:

Fig. 3.43
Tienes este ejemplo en el proyecto que acompaña el libro. No debes tener ningún problema si creas nodo por nodo. Cuando tengas que ponerle textura utiliza los que vienen en los Standard Assets.

1. Importar los modelos
En este capítulo vamos a trabajar con modelos, materiales, texturas y crearemos nuestros prefabs con colisionadores para construir nuestro nivel. Para seguir este capítulo puedes crear un proyecto nuevo e importar el paquete de assets que viene con el material del libro o puedes abrir el proyecto Construcción escenario modular.
Antes de empezar vamos a importar el material de este capítulo 4. Primero debes tener localizada la carpeta con el proyecto de este capítulo y acceder desde la barra principal Assets > Import Package > Custom Package y seleccionar el paquete de este capítulo que tiene el nombre de Modelos_Capitulo 4.unitypackage.
En el proyecto verás que en la ventana Protector tenemos una carpeta con el nombre Mi_Escenario que contiene las siguientes carpetas:

Fig. 4.1
Antes de continuar vamos a crear las carpetas que nos van a hacer falta. Así pues crearemos las siguientes carpetas dentro de Mi_Escenario.
•Materiales
•Prefabs
•Escenas
La ventana inspector debería quedarte como te muestro en la siguiente imagen:

Fig. 4.2
2. Modelos
En esta carpeta tenemos los modelos que han sido creados con un programa de 3d como puede ser Blender, Maya, Lightwave, Modo, Cinema4D etc. En este libro no se enseña cómo se crean estos modelos pero si como podemos trabajar con ellos en Unity.
Si seleccionamos uno de los Modelos, por ejemplo el que tiene como nombre Caja_1, veremos que tiene un añadido en su interior como te muestro a continuación:

Fig. 4.3
Al seleccionar un Modelo verás que en la ventana inspector aparecen una serie de propiedades del modelo que corresponden a la configuración de su importación. En este apartado disponemos de tres propiedades a configurar dependiendo del modelo.

Fig. 4.4
•Model: Esta opción contiene todos los parámetros que debemos tener en cuenta sobre la superficie del modelo, que se agrupa en 3 secciones : Meshes (Superficies), Normal & Tangents (Referente a la dirección de las normales de las superficies del modelo) y Materials (Materiales).
•Rig: En el caso de que el modelo sea un personaje es posible importar un rig.
•Animations: Algunos modelos pueden llevar animaciones.
Para este capítulo solamente vamos a utilizar el modelo como superficie y no vamos a tener ni rig ni animaciones.
Otro aspecto interesante que puedes observar en la ventana inspector es una muestra del modelo visualizado en la parte inferior.

Fig. 4.5
En la imagen anterior el cubo de la izquierda es el modelo con una material por defecto como lo veras en la escena y el cubo de la derecha te muestra la superficie con un número de vértices y triángulos.
Nuestro modelo en escena
A continuación vamos a poner algunos modelos en escena para trabajar con ellos. Para empezar vamos a seleccionar y a arrastrar dentro de la ventana Hierarchy (Jerarquía) 3 modelos; Suelo_1, Pared_Principal_1 y la Caja_1 .
No te preocupes si te quedan un poco desubicados en la escena, porque lo importante es que te queden de una forma parecida a la que te muestro a continuación:

Fig. 4.6
3. Materiales y texturas
De momento nuestros modelos no son gran cosa y es porque tienen un material por defecto que no tiene textura. Bien ahora vamos a crear materiales para nuestros modelos, para ello en la ventana Project accedemos a la carpeta Materiales y dentro de ella crearemos un material pulsando botón derecho del ratón y seleccionando la opción Create>Material y le ponemos el nombre de Caja_1.

Fig. 4.7
A continuación vamos a ponerle textura a este material pero antes en el menu Shader donde pone Standard le damos clic y seleccionamos la opción Standard (Specular setup) como te muestro en la siguiente imagen:

Fig. 4.8
Ahora asegúrate de que Rendering Mode se encuentra con la opción Opaque (Opaco) y haz clic encima del punto que encontraras en la opción Albedo. Se abrirá una nueva ventana con las texturas que se encuentran en la carpeta Texturas, selecciona la textura Caja_Difuse.

Fig. 4.9
Ahora selecciona el material Caja_1 desde la ventana Project y arrástralo encima del modelo Caja_1, como te muestro en la imagen siguiente.

Fig. 4.10
Ahora vemos cómo se le aplica el material al modelo caja_1. El siguiente paso es ponerle al material las texturas de Specular, Normal Map y Occlusion como hemos hecho con Albedo. Te dejo una captura de cómo me quedan los parámetros del material Caja_1 y cómo se ve el modelo en escena.

Fig. 4.11
Un apunte que debes tener en cuenta es que cuando le pongas la textura Normal Map, deberás pulsar el botón Fix Now para que se aplique este tipo de textura.

Fig. 4.12
Ahora es el momento de que crees los materiales que faltan para los distintos modelos, para que tengas una pequeña guía de te doy una pista de cuantos materiales debes crear en la siguiente imagen:

Fig. 4.13
En realidad solamente tienes que crear dos materiales más el de la Caja_2 y otro que he llamado Escena_General que sirve para el resto de modelos. Una vez tengas estos materiales pon todos los modelos en escena y arrastra sus respectivos materiales.

Fig. 4.14
El sombreado de los materiales
Cuando creamos materiales Unity utiliza dos opciones de sombreado el Standard “metallic”y el Standard (Specular setup).
•Standard ”metálico” dispone de una valor entre (0-1) que identifica si es metálico o no. Si el valor es 1 el parámetro color Albedo controla el color del reflejo especular y la mayoría de la luz se refleja. Cuando el valor es 0 el reflejo especular tendrá el color de la luz proyectada y la superficie de este material apenas tendrá reflejo.
•Estándar “especular” en este caso el color especular se utiliza para controlar el color y la fuerza de las reflexiones especulares en el material. Esto nos permite tener un reflejo especular de un color diferente al reflejo difuso.

Fig. 4.15
4. Parámetros básicos de los materiales
Ahora que has trabajado un poco con los materiales te resumo sus características más destacadas, para que en un futuro cuando crees tus propios modelos puedas utilizar materiales correctamente.
Rendering Mode
En este apartado nos encontramos con un desplegable en donde podemos seleccionar entre cuatro opciones. El parámetro en sí está enfocado en la transparencia del objeto.

Fig. 4.16
•Opaque (Opaco): es el valor predeterminado y adecuado para objetos sólidos normales sin áreas transparentes.
•Cut out (Recortar): le permite crear un efecto transparente que tiene bordes duros entre las áreas opacas y transparentes. En este modo, no hay áreas semitransparentes, la textura es 100% opaca o invisible. Esto es útil cuando se usa transparencia para crear la forma de materiales como hojas o tela con agujeros y jirones.
•Transparent (Transparente): adecuado para la representación de materiales transparentes realistas, como plástico transparente o vidrio. En este modo, el material tomará valores de transparencia (basados en el canal alfa de la textura y el alfa del tint colour), sin embargo, los reflejos y las iluminaciones se verán con toda claridad, como en el caso de los materiales transparentes reales.
•Fade (Fundido): permite que los valores de transparencia desvanezcan por completo un objeto, incluidos los reflejos o reflejos especulares que pueda tener. Este modo es útil si quieres animar un objeto que se desvanece hacia adentro o hacia afuera. No es adecuado para la representación de materiales transparentes realistas.
Main Maps (Mis mapas)
En este apartado disponemos de varios parámetros en donde utilizaremos mapas de textura según necesitemos para nuestros modelos.
Albedo
Controla el color base de la superficie.

Fig. 4.17
Si disponemos de una textura esta se representara en el objeto. En el caso anterior sucede para materiales opacos pero en el caso de que tengamos un material transparente este parámetro puede controlar la transparencia del material con una textura, los valores son blanco completamente opaco y el negro totalmente transparente.

Fig. 4.18
Modo Specular parámetro Specular
Son esencialmente los reflejos directos de las fuentes de luz en su Escena, que generalmente se muestran como reflejos brillantes y brillan en la superficie de los objetos (aunque los reflejos especulares también pueden ser sutiles o difusos).
Cuando se trabaja en modo Especular, el color RGB en el parámetro Especular controla la intensidad y el matiz del color de la reflectividad especular. Esto incluye el brillo de las fuentes de luz y los reflejos del entorno.

Fig. 4.19
Cuando ponemos una textura al parámetro Specular, tanto el parámetro Specular como el control deslizante Smoothness desaparecen. Por otro lado, los niveles especulares para el material están controlados por los valores en los canales Rojo, Verde y Azul de la Textura y los niveles de Suavidad para el material están controlados por el canal Alfa de la misma Textura. Esto nos unifica el trabajo porque una misma textura define como van a ser las áreas ásperas, lisas, una diferentes valores para la especularidad del objeto.

Fig. 4.20
Modo Metallic parámetro Metallic
En este modo a pesar del gran parecido al del Specular la reflectividad y el comportamiento de la luz en este tipo de material es variado por los parámetros Metálico (metallic) y el nivel de suavizado (Smoothnes). Estos dos parámetros bien configurados también nos proporcionan las reflexiones especulares que se siguen generando.

Fig. 4.21
Este Modo sera el que te ponga Unity por defecto siempre que crees un material nuevo, porque a pesar de que se llame Metallic no es solo para materiales metálicos, la razón es que este parámetro intenta determinar cuánto se parece el material que estás creando a uno metálico. Para que entendamos este concepto debemos entender que en una textura el color blanco representará el valor máximo de Metallic y el color negro es el valor mínimo de Metallic. De este modo, si tenemos un material para el traje de un guerrero que tiene partes de cuero y metálicas podremos determinar qué zonas deben tener mayor reflexión.
En el caso de que no tengamos ninguna textura este parámetro lo controlaremos mediante un deslizador entre los valores 0 y 1.

Fig. 4.22
Smoothness
Este parámetro se utiliza tanto en el modo metálico como en el modo especular proporcionando un servicio similar. En mi apreciación personal cuanto más nos acercamos al valor (1) del deslizador mayor es la concentración de la espectacularidad del material tanto en el modo metálico como el modo especular, por el contrario se disipa o suaviza cuanto más nos acercamos al valor (0).

Fig. 4.23
Normal Map
Este tipo de mapas nos permite representar relieve en nuestros modelos a pesar de que estos sean simples planos. Este tipo de texturas son muy utilizadas en los videojuegos, ya que nos permiten dar detalle a nuestros modelos. En los modelos importados de este capítulo puedes ver algunos mapas normales para los modelos que son en realidad cubos.
Los mapas normales son un tipo de mapa de relieve. Son un tipo especial de textura que le permite agregar detalles de la superficie, como protuberancias, ranuras y arañazos, a un modelo que capta la luz como si estuvieran representados por una geometría real. Este tipo de materiales se pueden crear con programas de diseño en 3D.

Fig. 4.24
Height Map
Este tipo de mapas o texturas tienen una función parecida a la de las normal maps pero en este caso es mucho más complejo ya que requieren más geometría para que el resultado sea aceptable. El objetivo es también crear relieve en una superficie en el ejemplo del capítulo no utilizaremos ninguna, pero este tipo de texturas se utilizan muchas veces para dar detalles adicionales a superficies con bastante geometría como los terrenos.

Fig. 4.25
Este tipo de mapas son en tonos de grises en donde el color blanco representa la zona más alta y el color negro la zona más baja.
Oclusion Map
Este tipo de texturas son mapas que intenta crear una iluminación ambiental y es un añadido a la textura principal. Es decir las partes cóncavas de un modelo serán oscurecidas, dando mayor sensación de profundidad. En muchos casos este parámetro combinado con el de normales ayuda a definir mejor el relieve y que se pueda apreciar mejor los detalles de un modelo.
Este tipo de texturas son imágenes en escala de grises, en donde las zonas en blanco son las zonas en donde la iluminación es directa y las zonas negras son donde no recibe iluminación. Este tipo de texturas se suelen crear con programas de creación 3d.

Fig. 4.26
Emission
Este parámetro cuando lo activamos es posible hacer que nuestro material emita luz y poder controlar el color y la intensidad de este. También nos permite incorporarle una textura. Un ejemplo que puedes ver en el ejemplo de este capítulo es la caja dos que dispone de una textura con fondo negro en donde solamente están en blanco las zonas que se quieren iluminar.
Luego puedes utilizar la caja selectora de color para ponerle el color que desees y en la caja de su lado derecho ponerle un valor para la intensidad.

Fig. 4.27
Detail Mask
Este parámetro permite utilizar una textura que actúe en forma de máscara para esconder ciertas zonas de nuestro modelo para aplicar otro tipo de detalle. En otras palabras, sería una forma de mostrar una parte de la textura en ciertas zonas que queremos que se muestren y esconder otras zonas de la textura que no queremos que se muestren. En este capítulo no vamos a entrar en detalle con este parámetro puesto que las texturas ya están preparadas para los modelos.
Parámetros de escalado y repetición
Esta zona se compone del Tiling en donde podemos especificar cuantas veces repetimos una textura en los ejes (X) e (Y) y el Offset para desplazarla en los ejes anteriores. Estos parámetros los podemos utilizar siempre que tengamos texturas con un patrón de repetición en estos ejes, si no es el caso es mejor no utilizar estos parámetros.

Fig. 4.28
Secondary Maps
Unity nos permite añadir un segundo conjunto de texturas sobre las que tenemos ya aplicadas. Esto es útil cuando queremos agregar algún detalle extra a nuestros modelos. Como hemos dicho en el apartado de escalado y repetición el tipo de texturas que se suele utilizar en estos dos parámetros suelen ser texturas preparadas para repetirse en gran escala.
5. Colliders y Rigid Bodies
Los colliders son un componente de los Gameobject se adaptan a la forma de nuestros modelos en cierto modo y crean colisiones. Este componente no lo tienen nuestros modelos por que han sido importados. Los colliders nos permiten que el objeto cree una colisión con otros objetos cuando estos trabajan con físicas.
Todos nuestros modelos deben tener un collider, para que más adelante nuestro player no atraviese las paredes o se caiga en el espacio infinito. Para ponerles un collider debemos seleccionar el objeto desde la ventana Jerarquía o la ventana escena, y desde la ventana inspector añadirle un collider desde Add Component >Physics > Box Collider. En este caso como todos los modelos son formas cuadradas utilizaremos el Box Collider como te muestro a continuación:

Fig. 4.29
El Box Collider anterior es la caja representada en color verde, en la imagen se ha exagerado el tamaño para que se diferencie bien del modelo. Normalmente cuando creas un componente collider este se adapta automáticamente al modelo. Para cambiar el tamaño puedes utilizar el botón Edit Collider y hacerlo desde la ventana escena o puedes utilizar las cajas de valores del apartado Size.
Un Rigidbody es otro componente de un Gameobject que creará un comportamiento físico en nuestros modelos. Este componente Rigidbody se lo vamos a aplicar a las dos cajas que tenemos en nuestra escena. Esto provocará que nuestras cajas reaccionen a la gravedad y reaccionaran a las colisiones.

Fig. 4.30
Antes de continuar, si estas siguiendo el capítulo mientras realizas las tareas que te propongo,te habrás encontrado con un inconveniente en el modelo Rampa, puesto que tiene una inclinación y el componente collider toma todo el ancho y todo el alto del modelo. Esto es un problema muy común con los modelos de este tipo vamos a ver como resolverlo.

Fig. 4.31
•Primero borra el componente collider del modelo de la rampa.

Fig. 4.32
•Dirígete a la ventana Jerarquía y en el botón Create seleccionamos la opción Empty.
•Se creará un GameObject vacío el cual le pondremos el nombre Collider_Rampa.
•A este GameObject le añadiremos un BoxCollider y lo escalaremos y lo posicionaremos de manera que se adapte lo máximo posible al modelo.
•Para finalizar arrastra el GameObject Collider_Rampa encima de Rampa para que se emparenten y de este modo ya tenemos el collider.

Fig. 4.33
Ahora podemos controlar el objeto Collider_Rampa que es hijo de Rampa utilizando las herramientas de escalado rotación y desplazamiento podemos darle la inclinación que deseemos. Voy a realizar capturas del proceso para que puedas ver como lo hago.
Primero debes utilizar el Gizmo de la ventana Vista y proyectar la vista que se parezca a la que te muestro a continuación:

Fig. 4.34

Fig. 4.35
Si todo es correcto debería quedarte la rampa como se muestra en la última imagen. A continuación veremos como preparar nuestros Prefabs para empezar a montar nuestro escenario modular.
6. Model vs Prefabs
Un archivo de modelo puede contener un objeto 3D, como un personaje, un edificio o un mueble. Este modelo es importado como activos múltiples, en donde suele contener la malla del objeto.
Cuando hablamos de Prefabs estamos hablando de modelos que hemos configurado en Unity y están listos para ser usados. Es decir los Prefabs ya tienen sus texturas puestas, sus animaciones configuradas (si tienen animación), sus colliders, rigidbody etc.
Ahora accederemos a la carpeta Prefabs en la ventana Proyectos y explicaré dos modos de crear Prefabs.
El primero y el más sencillo es configurar nuestro modelo, con sus texturas y sus colliders en la ventana escena y luego desde la ventana Jerarquía seleccionamos el nombre del objeto y lo arrastramos en el interior de la carpeta. Este tomará un color azulado y ya tendrás tu Prefab para utilizarlo siempre que lo necesites.

Fig. 4.36
Otra forma es crear un Prefab vacío dentro de la carpeta Prefabs haciendo clic con el botón derecho del ratón y acceder a la opción Create > Prefabs como te muestro a continuación:

Fig. 4.37
Se creara un Prefab vacío al que le puedes poner el nombre que quieras. Esta forma es muy útil cuando quieres crear configuraciones distintas de tus modelos y guardarlos como distintos Prefabs. Por defecto el nuevo Prefab es de color blanco cuando está vacío, en el momento que nosotros arrastremos un modelo encima de este Prefab tomara el color azul y ya tendremos nuestro Prefab listo para usar.

Fig. 4.38
Ahora debes coger todos los modelos y crear un Prefab de ellos para el siguiente apartado en donde aprenderás a montar partes de un escenario modular.

Fig. 4.39
7. Montar un escenario simple
Este es el momento de colocar todos nuestros Prefabs de forma ordenada para crear una escena simple que podría ser el primer nivel de un videojuego. En la imagen siguiente tenemos un esquema de un escenario muy básico que hemos dividido en dos sectores.

Fig. 4.40
Sector A
Para el sector A primero vamos a crear un GameObject vacío con el nombre de Sector A. Ahora seleccionaremos el Prefab Suelo_1 y lo arrastramos en la escena. En la ventana Jerarquia seleccionamos el Prefab Suelo_1 y lo duplicamos haciendo clic con el botón derecho dentro de la ventana Jerarquía y seleccionando la opción Duplicate.

Fig. 4.41
Ahora vamos a colocar estas dos piezas una al lado de la otra bien encajadas para ello selecciona uno de los Prefabs en la escena y luego pulsa la tecla (V) del teclado y verás tu cursor se siente atraído por los vértices del Prefab. Con la tecla (V) pulsada arrastra tu cursor hasta el vértice opuesto del otro Prefab para que se pongan justo uno al lado del otro.

Fig. 4.42
Ahora seleccionamos estos dos Prefabs y los duplicamos a la vez, en este caso si queremos moverlos de forma que siga el espacio de la cuadrícula de la escena movemos los duplicados manteniendo pulsado la tecla_Control.

Fig. 4.43
Ahora debemos realizar esta acción varias veces hasta que tengamos el suelo de la superficie del sector A como te he mostrado en el dibujo del mapa del escenario. Una vez tengas una superficie parecida lo dejo a tu elección. Dentro de la ventana Jerarquía vamos a seleccionar todos los Prefabs del suelo y los arrastraremos dentro del GameObject vacío Sector_A. De este modo tendremos ordenados todos los Prefabs. Esto estaría bien para cuando tenemos solo un Prefab en un sector, pero a continuación debemos añadir Paredes y otros elementos, por ese mismo motivo podemos crear varios gameObjects vacíos que sean padres de los distintos elementos como te muestro a continuación:

Fig. 4.44
En la imagen anterior verás que en la ventana Jerarquía tenemos El Sector A que es padre de todos los objetos que hay en el escenario excepto la cámara y la luz. Después tenemos un objeto vacío con el nombre Suelo Sector A que contiene todos los Prefabs del suelo, y he añadido otro objeto vacío con el nombre Paredes Sector A que va a contener todas las paredes. Esta es la dinámica que vamos a seguir.
El siguiente paso es que vayas arrastrando en escena los Prefabs por tipo y vayas construyendo el sector A de una forma organizada. Los Prefabs puedes rotarlos y moverlos pero no escalarlos pues estos modelos se crearon de una forma muy simple para que encajaran entre ellos.

Fig. 4.45
El sector está casi finalizado, como puedes ver tenemos ordenado en la ventana Jerarquía el sector A con todos los elementos que la componen, pero en los Prefabs que he utilizado solo tienen un box collider las columnas las cajas y los pasamanos las paredes y los suelos no llevan porque quería mostrarte otra forma de crear colliders en un escenario y para ser más concretos en un sector específico.
Vamos a crear otro gameObject vacío con nombre CollidersSectorA. Este gameObject que acabamos de crear no tiene de momento ningún parentesco con ningún objeto de la escena. A este objeto CollidersSectorA vamos a agregarle varios componentes de tipo Box Collider que re-situaremos en este sector.

Fig. 4.46

Fig. 4.47

Fig. 4.48
Una vez que tengas el primer boxcollider colocado añadiremos otro componente del mismo tipo a nuestro objeto CollidersSectorA.

Fig. 4.49
Este nuevo collider lo debemos re-situar utilizando la opción Edit Collider del componente o introduciendo valores en las opciones Center o Size.

Fig. 4.50
Es una forma de poner colisionadores a nuestra escena, en vez de utilizar un colisionador para cada Prefab, utilizamos 5 colisionadores que abarcan las necesidades de las paredes y suelos. El sector debería verse de la siguiente manera:

Fig. 4.51
Ahora que ya tenemos el sector A terminado hacemos exactamente el mismo procedimiento para crear el sector B. Los elementos Rampa y Plataforma son elementos que no pertenecerán a ningún sector puesto que son conectores de estos. A continuación te muestro como debería quedar la escena según nuestro esquema.

Fig. 4.52
8. Importar Standard Assets y probar el escenario
En el proyecto de este capítulo podrás importar un paquete con Assets en el que encontraremos un Player en primera persona que utilizaremos para poder probar el escenario dentro del juego.
Una vez que cargues el paquete de Standard Assets accede a la carpeta Characters > FirstPersonCharacter > Prefabs > FPSController, arrastramos este FPSController dentro de la escena y lo posicionamos en el SectorA como te muestro a continuación:

Fig. 4.53
Ahora desactiva o borra la cámara que viene por defecto en la escena como te muestro a continuación.

Fig. 4.54
Bien ya tenemos el escenario y un FPS (jugador en primera persona), ahora es el momento de disfrutar, ejecuta el juego y explora el escenario que todo esté correcto.

Fig. 4.55

Fig. 4.56

1. Introducción
Este es el primer capítulo en donde vas a empezar a escribir código y tus primeros scripts. Este capítulo se enfoca en darte una base introductoria para que te resulte más sencillo entender los próximos capítulos en los que se empieza a programar el movimiento de nuestro personaje y en donde empezamos a utilizar la API de Unity.
Creando nuestro primer Script
Crea un proyecto nuevo en 3D con el nombre que quieras, por ejemplo capítulo 5. En la ventana Project vamos a crear dos carpetas una para guardar nuestras escenas y la otra para guardar nuestros scripts como te muestro en la imagen siguiente.

Fig. 5.1
Ahora vamos a crear un script dentro de la carpeta Scripts que hemos creado anteriormente. Seleccionamos la carpeta Scripts y hacemos clic con el botón derecho del ratón y seleccionamos Create > C# Script, automáticamente aparecerá un script con el nombre por defecto NewBehaviourScript.cs.

Fig. 5.2
Si quieres puedes cambiarle el nombre al script. A continuación hacemos doble clic encima del script y se nos abrirá el programa Monodevelop que nos servirá para editar nuestro script. En esta obra se ha transcrito todos los scripts para mayor entendimiento del lector y se mostrarán siempre en este recuadro que te muestro a continuación.
| Script: NewBehaviourScript.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine; |
| public class NewBehaviourScript : MonoBehaviour{// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {}} |
El primer bloque que encontramos en la parte de arriba:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
Son necesarias porque es la forma que tenemos en C# de llamar directamente al Engine de Unity y para que se utilicen las colecciones genéricas para empezar a programar. Normalmente cuando creas un script en Unity ya se crean automáticamente, pero en algunos casos deberemos ser nosotros mismos los que agreguemos alguna otra colección.
public class NewBehaviourScript : MonoBehaviour
Este código que vemos es el nombre de la clase que siempre debe ser el mismo que el nombre del script y después de los dos puntos nos indica a que clase pertenece y en este caso y siempre por defecto pertenecerá a MonoBehaviour. Esta clase debe contener en su interior todo el contenido de nuestro script o dicho de otra manera el comportamiento que queremos que se ejecute.
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
En este bloque o parte del script es donde declararemos variables y utilizaremos nuestras funciones. En el script tenemos dos comentarios que sirven para informar y siempre van después de // y dos funciones (void Start) y (void Update) que veremos a continuación para que sirven.
Void Start
Para entender cómo funciona vamos a crear un mensaje para cada función que se va a mostrar por la ventana de Consola en Unity. Cuando queremos imprimir un mensaje debemos escribir la palabra Debug.Log(“”); Dentro del paréntesis de momento vamos a escribir entre comillas cuándo queremos poner texto, más adelante veremos qué opciones tenemos. A continuación te dejo el código que me gustaría que probarás.
| Script: NewBehaviourScript.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class NewBehaviourScript : MonoBehaviour{void Start (){Debug.Log(“Nuestro primer mensaje”);}void Update (){Debug.Log(“Este mensaje se va a repetir infinitas veces!!”);}} |
Una vez hayas escrito el código en tu script debes guardar el archivo seleccionando en la barra de herramientas principal File > Save. Ahora minimizamos el editor Monodevelop y nos dirigimos a Unity. Debes localizar la ventana Console en la interfaz si no lo ves puedes abrir esta ventana accediendo al menú principal en la opción Window > Console. Se abrirá la ventana Consola como te muestro en la siguiente imagen.

Fig. 5.3
Ahora para que nuestro script funcione debemos agregarlo a un objeto en la escena, como no tenemos ninguno debemos crear un GameObject vacío, o por defecto el que tú quieras y arrastrar el script encima del objeto dentro de la ventana jerarquía o con el objeto seleccionado arrastrando el script encima de sus componentes como te muestro a continuación en la siguiente imagen:

Fig. 5.4
Bien agregado el script ejecutamos el juego haciendo clic en play y pasados unos segundo veremos el siguiente mensaje en consola:

Fig. 5.5
El primer mensaje que se imprime en la consola es el que estaba dentro de la función Start si te fijas verás que solo aparece una vez. El segundo mensaje se repite en este caso 146 veces. Verás que he marcado la opción Collapse para que el segundo mensaje que estaba dentro de la función Update no me salga repetido y solamente se muestre una vez con el numero de repeticiones al lado.
2. Crear y manipular variables
Las variables son contenedores de información, por ejemplo imagínate que tienes tres amigos: Juan, Antonio y María. Ahora imaginate que utilizamos un nombre en clave para referirnos a estos tres amigos. El nombre clave es “jam” que son las letras del principio del nombre. Bien cada vez que digas jam estarás refiriéndote a tus 3 amigos, eso mismo es lo que hacemos en programación, damos un nombre fácil de recordar a un valor complejo.
Cuando creamos variables decimos que las estamos declarando y existen varios tipos de variables según el contenido que queremos guardar. Para declarar una variable en C# primero debemos decir si es pública o privada;
Las variables publicas nos permiten comunicar entre los scripts del mismo GameObject y otros GameObjects y se verán publicadas en la ventana Inspector de Unity.
Las variables privadas también nos permiten comunicar entre los scripts del mismo u otros GameObjects pero no se verán publicadas en la ventana Inspector de Unity.
Public/private+ tipo de variable + nombre de la variable;
Para el ejemplo en Unity crea un nuevo GameObject (un cubo) luego crear un nuevo script y llámalo Variables.cs y añadelo al nuevo GameObject:
| Script: Variables.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Variables : MonoBehaviour{public int edad = 56;public string nombre = “Oscar”;public float peso = 1,85f;void Start (){Debug.Log(“Mi nombre es: “+this.nombre+” tengo “+this.edad+” y mido “+this.peso);}} |
| Las variables declaradas son:•int para valores enteros.•string para valores de cadena de textos siempre entre comillas.•float para valores decimales y el numero debe finalizar con la letra f.Para mostrar en consola las variables se utiliza un Debug.Log y dentro del paréntesis se concadena con signos de suma con el nombre de las variables. El término this se utiliza para hacer referencia a la variables del objetos que tiene el script. |
Unity nos permite ver las variables que hemos declarado en la ventana inspector porque las hemos declarado públicas, como te muestro en la imagen siguiente:

Fig. 5.6
En la imagen anterior, seleccionando el objeto al que le hemos añadido el script nos muestra las variables que hemos declarado públicas en la ventana inspector. Si ejecutamos el juego haciendo clic a play en la consola debería aparecer el mensaje que hemos escrito dentro de la función Start.

Fig. 5.7
3. Trabajar con operadores aritméticos
Los operadores aritméticos nos permiten realizar operaciones con nuestras variables es decir si tenemos una variable energía = 100 y un enemigo te dispara con un arma de daño= 50 tu energía se le restará 50.
A continuación te muestro todos los operadores que necesitas para hacer tus operaciones. Primero cómo asignamos una operación a nuestras variables:
| Suma | x = x + y; | Módulo | x = x % y; |
| Resta | x = x - y; | Añadir 1 | ++x |
| Multiplicación | x = x * y; | Quitar 1 | --1 |
| División | x = x / y; |
Vamos a crear un ejemplo para ver como podemos utilizar estos operadores para ello crearemos un nuevo script en C# llamado Aritmeticos.cs (El nombre procura que sea sin acentos y sin la ñ).
Debemos calcular la velocidad que tiene nuestro objeto sabiendo la distancia recorrida y el tiempo que hemos utilizado.
| Script: Aritmeticos.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Aritmeticos : MonoBehaviour{private float velocidad;public float tiempo = 5,1f;public float distancia = 8.1f;void Update (){this.velocidad= this.distancia/this.tiempo;Debug.Log(“Mi velocidad es de: “+this.velocidad);}} |
| Las variables declaradas son todas float y públicas excepto la de velocidad porque quiero que solo se muestre en consola. Le hemos dado valores a la variable tiempo y a la variable distancia.He creado la operación dentro de la función Update para que cuando ejecutemos el juego y cambiemos los valores de tiempo y de distancia, Unity calcule de nuevo los nuevos valores.Para mostrar en consola el resultado de velocidad utilizamos un Debug.Log. |
En Unity podemos borrar el componente script anterior y añadir este nuevo al cubo. El resultado debería verse de la siguiente manera.

Fig. 5.8
4. Operadores lógicos y de comparación
Los operadores lógicos sirven para obtener dos resultados verdadero o falso estos resultados se les conoce también como valores Booleanos. A continuación te muestro las operaciones:
| && | And (y) | La operación seria verdadero y falso = falso |
| || | Or (o) | La operación seria verdadero o falso = verdadero |
| ! | Not (no) | La operación seria verdadero no = falso |
No tienes que memorizarlo simplemente debes saber que son y para que sirven. A continuación te muestro los operadores de comparación que nos permiten comparar valores en general.
| == | igualdad | 5==5 |
| != | desigualdad | 4!=0 |
| > | Mayor que | 10>2 |
| < | Menor que | 2<10 |
| >= | Mayor o igual que | X >= 10 // La x puede ser 10 o mayor que 10 |
| <= | Menor o igual que | X <= 10 // La x puede ser 10 o menor que 10 |
Este apartado es una especie de esquema en donde te muestro los operadores lógicos y de comparación en el siguiente apartado vamos a ponerlos en practica.
5. Crear declaraciones lógicas con if - else
En la vida diaria tomamos decisiones a cada momento un café (solo o con leche, con azúcar o sacarina etc). Según nuestra toma de decisiones suceden acontecimientos, es decir, imagínate tu personaje en una gruta con dos posibles salidas; la salida de la izquierda o la salida de la derecha.
Resulta que si escoges la de la derecha encuentras el tesoro y si escoges la salida izquierda se te come un dragón. De eso se encarga la declaración if, de comparar situaciones o valores y darnos un resultado según nuestra decisión.
Para declarar un if debemos escribirlo de la siguiente forma:
| if (x>0){Lo que sucede si se cumple la comparación del if ;}else{Si no se cumple el if pasara esto ;} |
Vamos a crear un script llamado Comparaciones.cs. En este ejemplo vamos a comparar las mejores puntuaciones de un juego. Tenemos 1 jugadores con 1 puntuación que podremos variar. Si el resultado de estas puntuaciones es >=100 el resultado es Experto si el resultado es >= 50 y <100 el resultado es intermedio y si no se cumple lo anterior es principiante.
| Script: Comparaciones.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Comparaciones : MonoBehaviour{private int puntuacion = 35;// Puedes poner el valor que quierasvoid Update (){if (puntuacion >= 100){Debug.Log (“Experto”);} else if (puntuacion < 100 && puntuacion >= 50){Debug.Log (“Intermedio”);}else{Debug.Log (“Principiante”);}}} |
El siguiente script cuando lo ejecutes en Unity podrás variar la puntuación y en la consola te irán apareciendo los distintos resultados posibles.

Fig. 5.9
6. Crear declaraciones con switch
El switch nos permite tomar de una sola variable su valor y realizar múltiples operaciones dependiendo del valor de la variable.
Para declarar un switch debemos hacerlo de la siguiente manera:
| Switch (variable){case “valor1”:Debug.Log(“Sucede algo”);break;case “valor2”:Debug.Log(“Sucede algo”);break;default:break;} |
Vamos a realizar un ejercicio muy básico para mostrar las posibilidades de switch. Imagínate que tenemos dos valores para una variable el valor 1 y el valor 2 y queremos que cuando tengamos el valor 1 nuestro personaje tenga una pistola y cuando la variable tenga el valor 2 tenga una escopeta. Para realizar el ejercicio crea un script con el nombre Switch.cs y lo añadimos al cubo, asegúrate de borrar el otro script de la ventana inspector para que solo tenga este script.
| Script: Switch.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Switch : MonoBehaviour{public int arma;void Start (){switch (arma){case 1:Debug.Log(“Pistola”);break; |
| case 2:Debug.Log(“Escopeta”);break;default:Debug.Log(“Nada”);break;}}} |
En la ventana inspector puedes poner el valor uno y te en la consola te mostrará una pistola y si pones el valor 2 te mostrará escopeta, si pones un valor distinto te mostrará el mensaje por defecto que es nada.

Fig. 5.10
7. Trabajar con loops
Un loop es un bucle una repetición de una condición o serie de condiciones un cierto número de veces o hasta que se cumpla una alguna de estas condiciones. Tenemos que tener cuidado con los loops porque si nos equivocamos podemos crear un loop infinito y bloquear Unity.
While
El primero de los loops que vamos a ver es While que nos permite crear un bucle hasta que se cumple la condición.
| Variable = 0;while (variable <= 10){Debug.Log(variable);variable++;} |
| Primero declaramos una variable con un valor en este caso 0.Le decimos a while que la condición es que mientras el valor de la variable sea menor o igual a 10 nos muestre por consola el valor de variable pero para que no sea un bucle infinito el valor de la variable tiene que incrementarse 1 cada vez por eso se le añade variable++ |
#Ejemplo1 para Unity
Crea un script con el nombre While.cs. Vamos a crear un script que nos muestre las tablas de multiplicar.
| Script: While.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class While : MonoBehaviour{private int valor = 0;public int tabla;private int resultado;void Start (){while (valor <= 10){resultado = valor * tabla;Debug.Log (valor+” x “+tabla+” = “+resultado);++valor;}}} |
Ahora si vamos a Unity debemos poner el valor de la tabla que queremos que nos muestre por consola por ejemplo la tabla del 4 y al ejecutar el juego en la consola se nos mostrará la tabla del cuatro.

Fig. 5.11
For
El loop for nos permite definir su valor, su limite y su incremento. Es otro loop que podemos utilizar, para escribirlo debemos hacerlo de esta manera:
| for(x=0; x<= 10; x++){Debug.Log (x);} |
| El for contiene una variable x que es igual a 0 en un principio, después tiene la condición de que x tiene que ser menor o igual a 0 y para finalizar este valor se ira incrementando. Cada vez que se cumpla se mostrara en consola el valor de x.Esto quiere decir que se repetirá 10 veces y que por consola se nos va a mostrar los valores 0,1,2,3,4,5,6,7,8,9,10. El valor 10 es el ultimo ya que el valor 11 sería mayor que 10 y no se cumpliría la condición de x<=10. |
Ahora que sabemos como utilizar el loop for vamos a realizar el mismo ejemplo que con el loop While de manera que crearemos un script que nos muestre las tablas de multiplicar según el valor de la tabla que queramos.
| Script: For.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class For : MonoBehaviour{public int tabla;private int resultado;private int valor;void Start (){for(valor=0; valor<= 10; valor++){resultado = valor * tabla;Debug.Log (valor+” x “+tabla+” = “+resultado);}}} |
El resultado debería ser exactamente igual al del ejemplo While descrito anteriormente.
8. Crear y llamar funciones
Ahora que sabemos qué son las variables, cómo podemos operar con ellas tomar decisiones y crear repeticiones según nuestras decisiones, vamos a comprimirlo todo en una función que nos permite contener múltiples acciones dentro, y para ejecutarla solamente necesitamos el nombre de la función.
Para crear una función debemos hacerlo de la siguiente manera:
| void nombredelaFuncion(){//Aqui ponemos la acción que queremos que ejecute.} |
Voy a seguir con el ejemplo de las tablas de multiplicar para que se entienda cómo podemos crear una función que me muestre la tabla de multiplicar que nosotros deseemos. Crea un nuevo script y llámalo Funciones.cs y añádelo al objeto que tengas en escena.
| Script: Funciones.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Funciones : MonoBehaviour{public int tabla;private int resultado;private int valor;void CreadorTablas (){for(valor=0; valor<= 10; valor++){resultado = valor * tabla;Debug.Log (valor+” x “+tabla+” = “+resultado);}}void Start(){this.CreadorTablas();}} |
| Después de declarar las variables hemos creado una función con el nombre de CreadorTablas, puedes ponerle el nombre que quieras. Después en su interior hemos creado el loop for que anteriormente habíamos visto para crear una tabla de multiplicar según el valor.Para llamar a la función debemos poner el nombre de la función como te muestro en el script dentro de la otra función Start. |
Si no sabes modelar en 3d no te preocupes porque este libro viene acompañado de material adicional para que puedas realizar los proyectos. En el caso de que quieras realizar algún proyecto distinto puedes descargar del Asset Store de Unity recursos en donde encontraras material gratuito y de pago.
9. Entender qué son los Arrays
Los Arrays son matrices que nos permiten almacenar múltiples objetos en una misma variable. Esta clase solo se encuentra en Javascript pero podemos utilizar en C# con las Buitlin arrays (que son nativas de .Net). Este tipo de Arrays son muy rápidas pero no pueden re-dimensionarse.
A continuación te muestro un ejemplo muy básico de cómo podemos utilizar estas Builtin arrays:
| Script: Arrays.cs |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Arrays : MonoBehaviour{public string[] lista;void Start(){this.lista= new string[4]{“Juan”,”Maria”,”Antonio”,”Lurdes”};foreach (string nombres in lista){Debug.Log(nombres);}}} |
| Primero declaramos una variable de tipo Builtin Array al que le damos el nombre de lista. Si te fijas verás que para decirle que el tipo primero ponemos el tipo de variable que será (int, string, float..) seguido de corchetes y luego le damos el nombre que deseamos.Dentro de la función Start le damos valores a la variable lista; para ello en C# siempre debemos añadir valores de la siguiente manera new string y entre corchetes puedes poner el numero de elementos o valores que va a tener el Builtin Array, seguido abrimos llaves y entre comillas ya que es de tipo string ponemos los nombres separados por comas.Para mostrar la lista he utilizado un foreach asignadole una variable de tipo string llamada nombre para mostrar cada elemento del Builtin Array de este modo cuando ejecutes el juego en la consola te mostrara todos los nombres de la lista. |
A continuación te muestro como deberías verlo en la ventana Inspector y en la consola.

Fig. 5.12
10. Mi primera clase
Hasta ahora el tipo de programación que hemos visto es secuencial es decir empezaba arriba y Unity lo ejecutaba de arriba a bajo. En la programación orientada a objetos (POO) es un poco mas compleja en el sentido de que esta basada en la comunicación entre objetos.
Para entender mejor este concepto vamos a realizar una serie de practicas.
1# Atributos
Vamos a crear una tabla de récords en donde cada jugador pueda introducir el nombre, y que nos diga el número de partidas jugadas, el tiempo invertido de juego y si el jugador está activo o no.
| Player 1 | Player 2 | Player 3 |
| Nombre stringpartidas inttiempo floatActivo bool | Nombre stringpartidas inttiempo floatActivo bool | Nombre stringpartidas inttiempo floatActivo bool |
Crea un nuevo proyecto llamado Programacion2 y crea una escena llamada clases. Crear un script C# con nombre infoPlayer. Intenta que el proyecto tenga sus carpetas con los scripts y las escenas ordenadas.
Crea un objeto vacío llamado TablaRecords y le ponemos un script con nombre tablaRecords. Ahora creamos un nuevo script sin añadirlo a ningún sitio y le ponemos el nombre de infoPlayer. Abrimos este script y le ponemos las siguientes variables.
| Script:infoPlayer |
| using System.Collections;using System.Collections.Generic;using UnityEngine;[System.Serializable]public class infoPlayer{public string nombre;public int partida;public float tiempo;public bool activo;} |
| En primer lugar, debes borrar todo lo que viene por defecto puesto que vamos a crear una clase que nos proporcione información del player y luego para que podamos ver las variables y los atributos en el inspector de Unity debemos escribir entre corchetes System.Serializable.El siguiente paso es crear una clase pública para poder acceder desde cualquier script y le ponemos el mismo nombre.Ahora solamente declaramos las variables que necesitamos; nombre partida tiempo y activo. |
| Script:tablaRecords |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class tablaRecords : MonoBehaviour{public infoPlayer player1;public infoPlayer player2;void Start (){this.player1.nombre = “Paco”;this.player1.partida = 8;this.player1.tiempo = 6.25f;this.player1.activo = true;this.player2.nombre = “Maria”;this.player2.partida = 2;this.player2.tiempo = 4.2f;this.player2.activo = false;Debug.Log (player1.nombre+”, “+ player1.partida +”, “+ player1.tiempo+” , “+ player1.activo);Debug.Log (player2.nombre+”, “+ player2.partida +”, “+ player2.tiempo+” , “+ player2.activo);} |
| Este script es el que hemos agregado al objeto en Unity. Desde aquí vamos a acceder a la clase infoPlayer para crear nuestros players.Si te fijas en la primera variable utilizo el nombre de la clase infoPlayer y le doy un nombre en este caso player1. Player1 es un nuevo objeto de la clase infoPlayer.Ahora en la función Start ya puedo acceder a sus atributos (es decir sus variables) para ello ponemos el nombre de la variable punto y si todo es correcto en monodevelop te aparecen los atributos. Escoge el que necesites y le das el valor que quieras, |
| En este ejemplo he puesto el player 1 y el player 2 a ti te dejo el 3.Para finalizar puedes mostrar en la consola los atributos de la clase. Recuerda que te aparecerán los valores cuando ejecutes el juego. |

Fig. 5.13
Si ejecutamos el juego veremos que en la consola aparecen los atributos y en la ventana Inspector las cajas de texto se llenan con los valores que les hemos asignado.

Fig. 5.14
2# Métodos
Si seguimos con el ejemplo anterior, también podemos crear funciones dentro de las clases. Para esta actividad vamos a crear una función que nos muestre por consola los atributos de la clase, para no tener que escribir tanto.
| Script:infoPlayer |
| using System.Collections;using System.Collections.Generic;using UnityEngine; |
| [System.Serializable]public class infoPlayer{public string nombre;public int partida;public float tiempo;public bool activo;public void MuestraInfo(){Debug.Log (“Nombre del jugador: “ + nombre);Debug.Log (“Numero de Partidas: “ + partida);Debug.Log (“Tiempo de juego: “ + tiempo);Debug.Log (“Actividad actual: “ + activo);}} |
| Creamos a continuación de las variables una función con el nombre que quieras en este caso es MuestraInfo y dentro escribimos varios Debug.Log con los mensajes y el nombre de la variable que deseamos que se muestren |
Ahora que hemos creado este método en la clase solamente debemos substituir en el script tablaRecords los debugs Logs por lo siguiente.
| Script:tablaRecords |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class tablaRecords : MonoBehaviour{public infoPlayer player1;public infoPlayer player2;void Start (){this.player1.nombre = “Paco”;this.player1.partida = 8;this.player1.tiempo = 6.25f;this.player1.activo = true;this.player2.nombre = “Maria”;this.player2.partida = 2;this.player2.tiempo = 4.2f; |
| this.player2.activo = false;this.player1.MuestraInfo(); this.player2.MuestraInfo();}} |
3# Constructor básico
Creamos funciones dentro de una clase para que se ejecuten cuando creamos un objeto de esa clase; o, dicho correctamente, se instancia un objeto de esa clase.
En los ejemplos anteriores hemos creado 2 players y ahora en el script infoPlayer vamos a crear el constructor de la clase, que nos va a informar de que se ha creado un nuevo objeto de esta clase.
| Script:infoPlayer |
| using System.Collections;using System.Collections.Generic;using UnityEngine;[System.Serializable]public class infoPlayer{public string nombre;public int partida;public float tiempo;public bool activo; public infoPlayer(){Debug.Log(“Se ha creado un objeto de la clase infoPlayer”);}public void MuestraInfo(){Debug.Log (“Nombre del jugador: “ + nombre);Debug.Log (“Numero de Partidas: “ + partida);Debug.Log (“Tiempo de juego: “ + tiempo);Debug.Log (“Actividad actual: “ + activo);}} |
| Dentro de la clase; debemos crear después de los atributos una función pública con el mismo nombre de la clase dentro ponemos un mensaje. |
A continuación vamos a crear los objetos de la clase infoPlayer.
| Script:tablaRecords |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class tablaRecords : MonoBehaviour{public infoPlayer player1 = new infoPlayer();public infoPlayer player2 = new infoPlayer();void Start (){this.player1.nombre = “Paco”;this.player1.partida = 8;this.player1.tiempo = 6.25f;this.player1.activo = true;this.player2.nombre = “Maria”;this.player2.partida = 2;this.player2.tiempo = 4.2f;this.player2.activo = false;this.player1.MuestraInfo();this.player2.MuestraInfo();}} |
| Para crear un nuevo objeto diremos que la variable es igual a new seguido del nombre del constructor.Cuando ejecutes el juego en Unity si todo es correcto debe de mostrarte el mensaje que hemos escrito dentro del constructor. |
3# Constructor inicializando valores.
También podemos crear los objetos con valores directamente, esto quiere decir que cuando creamos el player1 ya le podemos poner los valores directamente y evitamos tener que escribir tanto código. Para ello vamos al script de la clase y creamos escribimos lo siguiente:
| Script:infoPlayer |
| using System.Collections;using System.Collections.Generic;using UnityEngine;[System.Serializable]public class infoPlayer{public string nombre;public int partida;public float tiempo;public bool activo;public infoPlayer(){Debug.Log(“Se ha creado un objeto de la clase infoPlayer”);}public infoPlayer(string n, int p, float t, bool a){this.nombre = n;this.partida = p;this.tiempo = t;this.activo = a;}public void MuestraInfo(){Debug.Log (“Nombre del jugador: “ + nombre);Debug.Log (“Numero de Partidas: “ + partida);Debug.Log (“Tiempo de juego: “ + tiempo);Debug.Log (“Actividad actual: “ + activo);}} |
| Ahora tenemos el constructor pero con una serie de argumentos.Dentro del constructor guardamos estos argumentos dentro de las variables que son los atributos que necesitaremos para crear un objeto de esta clase. |
| Script:tablaRecords |
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class tablaRecords : MonoBehaviour{public infoPlayer player1;public infoPlayer player2;void Start (){this.player1 = new infoPlayer(“Paco”,8,6.25f,true); this.player2 = new infoPlayer(“Maria”,2,4.2f,false);this.player1.MuestraInfo();this.player2.MuestraInfo();}} |
| Nuestro script tablaRecords quedará de la siguiente forma, |
Hasta aquí esta pequeña introducción a la programación en C#, no quiero entrar en muchos detalles de programación básica, sino explicarte un poco las reglas del juego. Estas son algunas de las habilidades que debes entender y utilizar a pesar de que te equivoques, porque en los próximos capítulos empezaremos a ver cómo este lenguaje nos permite controlar objetos y que estos interactúen. La estructura que debes comprender cuando hablamos del concepto, (principalmente abstracto), de programación es:
•Dispones de unas variables para almacenar información compleja.
•Puedes realizar operaciones, comparar valores y tomar decisiones con estas variables.
•Puedes automatizar con bucles operaciones que se repiten continuamente.
•Puedes agruparlo todo en una función para utilizarla más adelante.
•Puedes crear tus propias clases que encapsula todo lo anterior.
En el próximo capítulo empezaremos a poner en practica estos conceptos tan abstractos para que empieces a concretar tus objetivos.

1. Introducción
Una vez hemos visto el capítulo de programación básica es el momento de poner en práctica todo lo aprendido mediante actividades prácticas.
No pretendo que este libro se convierta en un simple conjunto de tutoriales, sino en una serie de ejercicios que te permita mejorar en el dominio de Unity.
Para esta tarea el vas a crear un nuevo proyecto llamado Capitulo 6. Una vez tengas abierto el nuevo proyecto, guarda el proyecto. Como ya sabes esta obra viene con material adicional para seguir los capítulos, ten localizado este material adicional para acceder a él.
Bien primero accedemos al menú principal y seleccionamos la opción Assets > Import Package > Custom Package. Se nos abrirá una ventana de navegación del sistema dependiendo de que sistema operativo tengamos Window, o Mac y debemos localizar dónde tenemos guardado el material adicional que acompaña el libro y seleccionar el paquete con el nombre Assets Capitulo6 dentro de la carpeta Proyecto_6.

Fig. 6.1
Después de seleccionar el paquete se nos aparecerá una ventana en Unity que nos muestra el contenido de este paquete y nos permite seleccionar que queremos importar del paquete. En nuestro caso vamos a dejarlo todo marcado y le daremos al botón Import.

Fig. 6.2
Si lo hemos importado todo correctamente deberías poder ver las siguientes carpetas en la ventana Project.

Fig. 6.3
Ya tenemos preparado el proyecto para seguir todas las pautas del capítulo que es uno de los más importantes si nunca has programado porque en este capitulo vamos a ver los siguientes apartados:
Las funciones que voy a mostrarte son referentes a la clase MonoBehaviour. Este primer apartado quiere ayudarte no solo a que entiendas cómo funcionan si no que aprendas también a consultar la documentación de Unity Scripting API. Puedes acceder desde el siguiente enlace:
https://docs.unity3d.com/es/current/ScriptReference/MonoBehaviour.html
Pero, ¿qué es la documentación de Unity? En la siguiente imagen te muestro con qué te vas a encontrar y cómo puedes utilizar esta documentación de una forma inteligente. He numerado las zonas que tienes que tener en cuenta para mejorar la comprensión.

Fig. 6.4
En el apartado A dispones de la versión de Unity a la que estás consultando la información, no quiere decir que de una versión 5,3 a la 5,4 varíe mucho pero es recomendable saber a qué version accedes en la información.
En el apartado B tenemos dos tipos de documentación, el Manual y el Scripting API. El Manual nos proporciona información de cómo utilizar Unity, sus ventanas paneles y todo lo referente al programa en sí y el apartado de API es toda una recopilación de Clases, funciones, variables, etc. que podemos utilizar en nuestros Scripts para programar en Unity.
En el apartado C verás que puedes seleccionar qué tipo de lenguaje quieres consultar en el apartado Scripting API. Solo hace referencia a las consultas de Scripting. En este libro utilizaremos solamente C#.
El apartado D nos da la posibilidad de buscar una palabra en concreto. Más adelante, cuando tengas dudas sobre algún método en concreto puedes ir directamente al buscador y poner el método que buscas. La documentación te proporcionará una lista con todos los métodos y clases relacionadas con esa palabra.
La zona marcada con una E es la información de la búsqueda en donde te proporcionan descripciones de los métodos y las variables que necesitas.
Por ultimo tienes la sección F que es una lista ordenada alfabéticamente con todas las clases que puedes encontrar en la documentación en el caso de la API, y en el caso del manual una lista organizada por temas referente al programa Unity.
En este enlace verás un apartado Mensajes que en realidad son eventos. Un evento según la programación en C# es cuando ocurre algo. Los eventos habilitan una clase u objeto para notificarlo a otras clases u objetos. La clase que envía el evento recibe el nombre de publicador y las clases que reciben el evento se denominan suscriptores.
Algunas características sobre los eventos:
•El publicador determina el momento en el que se genera un evento; los suscriptores determinan la acción que se lleva a cabo en respuesta al evento.
•Un evento puede tener varios suscriptores. Un suscriptor puede controlar varios eventos de varios publicadores.
•Nunca se generan eventos que no tienen suscriptores.
•Los eventos se suelen usar para indicar acciones del usuario, como los clics de los botones o las selecciones de menú en las interfaces gráficas de usuario.
Dicho lo anterior vamos a poner algunos ejemplos con un ejercicio. Aquí solo te voy a mostrar cómo se escriben dentro de un script y luego explico para qué sirven algunos:
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Evento : MonoBehaviour {void Awake(){Debug.Log(“Esto es el Awake”);}void Start(){Debug.Log(“Esto es el Start”);}void Update() |
| {Debug.Log(“Esto es el Update”);}void OnDisable(){Debug.Log(“El objeto está desactivado”);}void OnEnable(){Debug.Log(“El objeto está activado”);}void OnEnable(){Debug.Log(“El objeto está activado”);}void OnMouseDown(){Debug.Log(“El ratón hace click”);}void OnMouseEnter(){Debug.Log(“El ratón esta encima”);}void OnMouseExit(){Debug.Log(“El ratón sale fuera”);}} |
•Awake: es llamado cuando se carga el script y se utiliza para inicializar cualquier variable o estado del juego antes de que comience el juego. Este evento solo se llama una sola vez y después de cargar todos los objetos.
•Start: es llamado cuando se habilita un script y justo antes de llamar a cualquiera de los métodos de Update. Al igual que en el Awake solo se llama una sola vez y se ejecuta cuando activamos el juego.
•Update: repite todo lo que contenga a cada frame o cuadro. Este evento de MonoBehaviour es muy utilizado para crear comportamientos en un juego.
•OnDisable & OnEnable: hemos visto anteriormente cómo podemos activar y desactivar objetos desde la ventana inspector de Unity con estas funciones podemos activar o desactivar el objeto mediante programación.
•OnMouse(Enter,Down,Exit): nos permite saber cuando el usuario realiza una serie de acciones con el ratón.
Estas son algunas de las funcionalidades que podemos encontrar en la programación de videojuegos, a continuación iremos profundizando hasta que comprendas como funciona todo.
2. Clase GameObject
Como hemos hecho con los eventos, ahora vamos a acceder a la documentación de GameObject, si te resulta más cómodo te dejo el enlace a continuación o puedes escribir la palabra GameObject en el buscador de la documentación de Unity :
https://docs.unity3d.com/es/current/ScriptReference/GameObject.html
En la documentación encontramos varios aspectos importantes que vamos a tratar en este apartado, pero antes quiero que entiendas la diferencia entre GameObject en mayúscula y gameObject en minúscula.
Si recordamos cuando creamos un script y lo agregamos o arrastramos encima de un gameObject por ejemplo un cubo, dentro del script para referirnos a el cubo lo escribiremos en minúscula: gameObject. Si queremos hacer referencia a un GameObject externo o crear uno propio utilizaremos GameObject en mayúscula ya que en este caso hacemos referencia a la clase.

Fig. 6.5
En la imagen anterior representamos que un cubo se le añade un script, dentro del script cuando queremos referirnos al propio objeto utilizamos gameObject. En el caso de que el cubo quiera tomar referencia del objeto redondo dentro del script lo escribiremos en mayúscula GameObject.
Ahora en el proyecto de Unity accede a la carpeta Prefabs y arrastra un cubo al escenario o a la ventana Jerarquía como te muestro en la siguiente imagen:

Fig. 6.6
A continuación crea una carpeta nueva dentro de Project con el nombre Scripts. Si no recuerdas cómo se hace puedes seleccionar la carpeta Assets y pulsar en el botón Create y seleccionar la opción Folder. Te aparecerá una nueva carpeta a la que puedes ponerle un nombre, en este caso Scripts.

Fig. 6.7
Dentro de la carpeta Scripts vamos a crear un nuevo script con nombre Ejemplo1. Para crear un nuevo script hacemos doble clic encima de la ventana Scripts y dentro de ella hacemos clic en el botón derecho del ratón y en el menu que nos parece seleccionamos la opción Create > C# Script. Se nos aparece un nuevo Script que podemos renombrar, en este caso con el nombre Ejemplo1.

Fig. 6.8
Ahora seleccionamos el Cubo haciendo clic en la escena encima del objeto con el botón izquierdo o desde la ventana Jerarquía encima del nombre del objeto, en este caso con nombre cube. Luego arrastramos el script que hemos creado dentro de la ventana inspector o encima del nombre del objeto cube, como te muestro en la siguiente imagen:

Fig. 6.9
Para finalizar la preparación de la escena vamos a agregar otro prefab a la escena como hemos hecho con el cubo. Añadimos una esfera pero esta no debe llevar ningún script. Te muestro cómo debería quedar la escena:

Fig. 6.10
Ahora solo nos queda guardar la escena pero antes vamos a crear una carpeta en la ventana Project con el nombre de Escenas, como hemos hecho con la carpeta script. Para guardar la escena simplemente accedemos al menú y seleccionamos la opción File >SaveScene te aparecerá un ventana de tu sistema operativo dentro de la carpeta Assets, selecciona la carpeta que has creado llamada Escenas y ponle el nombre de Escena 1. Tu escena ha quedado guardada y podemos empezar el ejercicio.

Fig. 6.11
A partir de ahora los enunciados van a ser de la siguiente manera para agilizar el temario.
#1 En una nueva escena crear 2 GameObjects un cubo y una esfera (puedes utilizar los Prefabs del material importado). Añadir un script al cubo con nombre Ejemplo1. Para acceder al Script hacemos doble clic encima del archivo Script Ejemplo1 y Unity abrirá el editor Monodevelop y escribiremos el siguiente Script:
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Ejemplo1 : MonoBehaviour{void Start(){Debug.Log(gameObject.name);}} | Si te fijas dentro del Debug.Log hemos utilizado el gameObject en minúscula para referirnos al propio gameObject que en este caso es el cubo.También debes tener en cuenta que las clases tienen métodos y atributos uno de sus atributos es “name” que hace referencia al nombre del objeto. |

Fig. 6.12
Como puedes ver en la imagen anterior en consola se nos aparece el nombre Cube cuando activamos o ejecutamos la escena.
#2 Ahora vamos a cambiar el nombre que tiene el cubo. Si miras la documentación https://docs.unity3d.com/es/current/ScriptReference/GameObject.html verás que tenemos una variable o atributo llamado name que nos permite acceder al nombre del objeto, y en el ejemplo anterior lo hemos utilizado para que nos muestre el nombre, pero también podemos utilizarlo para cambiar el nombre.
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Ejemplo1 : MonoBehaviour{void Start(){gameObject.name = “Micubo”Debug.Log(gameObject.name);}} | Cuando activemos el script, es decir cuando le demos al play verás como cambia el nombre del cubo y como por consola aparece Micubo. |

Fig. 6.13
En el ejemplo anterior verás que mientras ejecutemos el juego el nombre del cubo cambia por el nombre de Micubo y puedes verlo en la ventana Jerarquía y en la ventana Inspector.
Hemos visto cómo acceder al gameObject en el que hemos aplicado el script, pero la pregunta es ¿cómo accedemos a un objeto externo?
#3 Ahora vamos a acceder desde el script ejemplo1 del cubo a los componentes del objeto Esfera, arrastrando el objeto a una variable pública de tipo GameObject.
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Ejemplo1 : MonoBehaviour{ public GameObject miEsfera;void Start() | Primero creamos una variable publica de tipo GameObject que nos permite almacenar objetos. La hacemos publica para que aparezca en la ventana inspector. |
| {gameObject.name = “Micubo”Debug.Log(gameObject.name); Debug.Log(miEsfera.name); }} | Lo segundo es que muestre por la pantalla de la consola el objeto miEsfera, pero esto no va a funcionar a no ser que al volver a Unity arrastremos el objeto Esfera encima de la ventana inspector, en donde está la variable miEsfera representada. |
Para el ejemplo 3 te muestro cómo queda una variable al hacerla pública en la ventana inspector.

Fig. 6.14
Como puedes ver en la imagen anterior, la variable al hacerse pública se muestra en la ventana Inspector con una caja de textos que pone None (Game Object) esto significa que no hay un objeto asignado para esta variable y debemos asignarlo. Ahora te muestro cómo podemos asignarle manualmente un objeto a esta variable.
Si hacemos clic encima del punto o símbolo en forma de punto que encontramos al final de la caja de textos accederemos a una ventana flotante en donde podemos seleccionar el objeto que queremos.

Fig. 6.15
Otra forma de realizar la acción anterior es seleccionar el objeto desde la ventana Jerarquía y arrastrarla encima de la caja de textos de la variable Unity lo asocia automáticamente.

Fig. 6.16
Ahora ejecutamos el juego y podremos comprobar en la consola cómo nos aparece el nombre del objeto Cube con el nombre cambiado y el nombre del objeto externo Sphere que hemos asociado manualmente desde Unity.

Fig. 6.17
#4 Nuestro siguiente paso es buscar el objeto esfera desde el propio script ejemplo1, pero debemos borrar la variable que hemos hecho anteriormente como te muestro en el siguiente script.
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Ejemplo1 : MonoBehaviour{ public GameObject buscarEsfera; |
| void Start(){gameObject.name = “Micubo”Debug.Log(gameObject.name); this.buscarEsfera= GameObject.Find(“Sphere”);}} |
| Creamos una variable de tipo GameObejct con un nombre el que quieras en este caso le he puesto buscar Esfera.el anterior script para eliminar la referencia que hemos puesto en la actividad anterior. También he borrado el Debug.Log que me mostraba el nombre de la esfera y solamente he dejado la del cubo.Al declarar la variable utilizo un método que puedes ver en la documentación llamado find. Este método buscará un objeto en la escena con el nombre que le pongamos entre paréntesis y comillas, en este caso el valor que le paso es el nombre del objeto Sphere. |
Una vez volvamos a Unity veremos que en la ventana inspector que tenemos una nueva variable con el nombre buscarEsfera, pero vuelve a estar vacía. Esta variable tomará la referencia de la esfera o, dicho de otro modo, buscará el objeto con nombre Sphere cuando ejecutemos el juego. En la siguiente imagen te muestro cómo se verá antes y después de ejecutar el juego.

Fig. 6.18
#5 Otra forma de buscar objetos sería igual que la anterior pero utilizando Tags (Etiquetas). Para realizar la actividad vamos a utilizar otro de los Prefabs que disponemos en el proyecto. Selecciona el Prefab Capsule y arrástrala a la escena. Teniendo seleccionada la cápsula accedemos a la ventana Inspector y en el apartado Tag desplegamos su menú y seleccionamos la opción Player.

Fig. 6.19
Ahora ya disponemos de un tercer objeto en escena llamado Capsule que ademas tiene una etiqueta con el nombre Player que nos permite desde el script del cubo acceder a él. Seguimos utilizando el mismo script Ejemplo1 como te muestro a continuación:
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Ejemplo1 : MonoBehaviour{public GameObject buscarEsfera;public GameObject buscarCapsula;void Start(){gameObject.name = “Micubo”Debug.Log(gameObject.name);this.buscarEsfera = GameObject.Find(“Sphere”); this.buscarCapsula = GameObject.FindGameObejctWithTag (“Player”);}} |
| Creamos una variable pública de tipo GameObject con nombre buscarCapsula, dentro del evento Start declaramos el valor de buscarCapsula que es un GameObject con una etiqueta “Player”.Cuando ejecutes el juego en esta variable aparecerá contenido el objeto capsule. |
Cuando vuelvas a Unity verás que en la ventana Inspector tenemos las variables declaradas públicas vacías, en el momento que ejecutemos el juego veremos cómo toman la referencia de los objetos.

Fig. 6.20
#6 Para finalizar este apartado tienes que saber que también puedes crear GamesObjects utilizando el constructor. El constructor de una clase GameObject tiene el objetivo de que puedas crear nuevos objetos de esa misma clase (como todos los constructores). Para que entiendas mejor a lo que me refiero es que podemos crear nuevos objetos dentro de la escena. Primero te voy a invitar a consultar la documentacion accediendo a este enlace.
https://docs.unity3d.com/es/current/ScriptReference/GameObject-ctor.html
Cuando creamos otro objeto este se crea por defecto con un componente Transform que veremos mas adelante en detalle.
A continuación te muestro como podemos crear un objeto nuevo desde un script.
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Ejemplo1 : MonoBehaviour{public GameObject buscarEsfera;public GameObject buscarCapsula; public GameObject nuevo;void Start(){gameObject.name = “Micubo”Debug.Log(gameObject.name);this.buscarEsfera = GameObject.Find(“Sphere”);this.buscarCapsula = GameObject.FindGameObejctsWithTag (“Player”); this.nuevo= new GameObject (“Nuevo”);}} |
Cuando actives el juego verás que se te aparece un objeto llamado Nuevo. Para mostrarte cómo se ve en Unity he capturado dos imágenes una antes de ejecutar el juego y la segunda imagen ejecutando el juego.

Fig. 6.21

Fig. 6.22
El nuevo objeto que se crea solamente tiene un componente transformación y nombre porque todo objeto en Unity debe tener estos componente como mínimo. También hay que decir que este objeto no tiene nada más y por ese motivo no se puede ver en la ventana escena. A estos objetos les llamamos objetos vacíos y ya los hemos utilizado para ordenar escenarios utilizándolos como padre de los demás objetos. Si tienes dudas puedes revisar el capítulo 4.
3. Acceder a los componentes
Seguimos con los GameObjects pero esta vez vamos a ver cómo acceder a los componentes de estos mismos. En los primeros capítulos vimos cómo crear gameObjects y cómo añadir componentes como un collider o materiales; ahora vamos a ver cómo podemos hacer esto mediante scripts. Supongo que te preguntarás por qué tienes que aprender a hacerlo mediante programación cuando puedes hacerlo por el editor; pues la respuesta es muy simple, en ocasiones deberás acceder mediante scripts para poder automatizar componentes en concreto, y porque te da una libertad increíble para trabajar en tus futuros proyectos.
Sé que me repito, pero te aconsejo que tengas la documentación accesible ahora que ya sabes cómo consultarla.
https://docs.unity3d.com/540/Documentation/ScriptReference/GameObject.html
Para explicar el siguiente apartado realizaremos varios ejemplos. Crea una nueva escena accediendo al menú principal en File > New Scene como te muestro en la siguiente imagen:

Fig. 6.23
Ahora verás que la escena ha quedado limpia. Seguidamente accede al menú principal otra vez y accede a la opción Save Scene. Ponle nombre Escena 2 y guarda la escena en la carpeta de Escenas. Dentro de la Escena 2 arrastra un Prefab cubo como te muestro en la siguiente imagen:

Fig. 6.24
Ahora crearemos un objeto vacío de forma manual, es decir, sin programación. Para ello hacemos clic encima de la ventana Jerarquía en el botón Create y seleccionamos la primera opción Create Empty. Automáticamente se nos aparecerá en la lista un nuevo objeto con nombre por defecto GameObject.

Fig. 6.25
#1 En el gameObject vacío le añadimos un script llamado Components. Cuando crees el nuevo script y le hayas puesto nombre guárdalo en la carpeta Scripts para mantener ordenado el proyecto. Dentro del Script Components vamos a cambiar el nombre y vamos a mostrar la posición en (x,y,z) por consola. Esto significa a que vamos a acceder a sus componentes, el del nombre ya lo hemos visto a continuación te muestro el script.
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class Components : MonoBehaviour {void Start(){gameObject.name = “Esfera”}void Update(){ Debug.Log(gameObject.transform.position);}} |
| Primero, como el script está dentro del objeto utilizamos directamente gameObject dentro de la función Start. Como vimos en el apartado anterior para cambiar el nombre utilizamos .name y le damos el valor del nombre entre comillas.Después, dentro de la función Update utilizamos el Debug.Log y dentro de los paréntesis hacemos referencia al objeto en sí como gameObject, seguido de un punto para acceder al componente transform. Esto nos devuelve 3 valores, uno para cada eje (x,y,z)Puedes cambiar el valor de x, y, z manualmente desde la ventana inspector para ver como cada vez te muestra por consola un valor distinto. Esto sucede porque dentro de la función update ser repite continuamente. |
A continuación te muestro el resultado que me muestra la ventana Inspector y la consola.

Fig. 6.26
Este ejemplo anterior simplemente es para mostrarte de que mediante programación podemos controlar con mucha precisión ciertos aspectos de los objetos. También verás que por consola solamente nos muestra un decimal en la posición. Antes de continuar quiero que entiendas que las transformaciones son de tres tipos:
•Posición: que nos permiten desplazar los objetos por toda la escena.
•Rotación: que nos permite rotar los objetos
•Escalado: que nos permite cambiar el tamaño de los objetos.
Todas las transformaciones se basan principalmente en tres ejes X, Y, Z que nos dan una posición, una rotación y un escalado más precisos. Estas tres coordenadas pueden ser de utilizadas de un modo Global o un modo Local. De momento vamos a ir viendo poco a poco los 3 tipos y cómo podemos acceder a ellos.
#2 Ahora creamos un nuevo script que llamaremos ComponenteExterior.cs; vamos a ver cómo accedemos al componente transform de un objeto externo, en este caso del cubo que tenemos en escena. Primero selecciona el GameObject vacío y le eliminar el script que tenía anteriormente de la siguiente manera:
Selecciona el GameObject vacío y, accediendo a la ventana Inspector en el componente Script, haz clic encima del símbolo que te marco en la imagen siguiente y en el menú que aparece seleccionamos la opción Remove Component; el componente script será eliminado.

Fig. 6.27
Ahora, si ya has creado el nuevo script con el nombre de ComponenteExterior.cs, se lo agregamos al Game Object vacío. El componente nuevo de tipo script debe quedar como en la siguiente imagen:

Fig. 6.28
A continuación te muestro el script que debe mostrarte la posición en cada eje por separado del Cubo. Recuerdo que estos ejercicios son para familiarizarnos con la forma de acceder a los componentes.
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class ComponenteExterior : MonoBehaviour |
| {public GameObject miCube;public float cubeX;public float cubeY;public float cubeZ;void Start(){this.miCube = GameObject.Find(“Cube”);this.cubeX = miCube.transform.position.x;this.cubeY = miCube.transform.position.y;this.cubeZ = miCube.transform.position.z;Debug.Log(cubeX);Debug.Log(cubeY);Debug.Log(cubeZ);}} |
| Primero debemos crear una variable de tipo GameObject para contener al cubo que he llamado miCubo y luego como necesitamos mostrar 3 valores con decimales he creado 3 variables de tipo float para los ejes del cubo x,y ,z.Dentro de Start primero vamos a buscar el objeto Cube que en este caso como solo hay un cubo podemos utilizar el método Find con el nombre “Cube”.Ahora ya tenemos el cubo dentro de una variable y podemos acceder a su primer eje de transformación. Por eso cojo las variables que he creado para almacenar el valor en x,y,z. Estas variables serán igual a la variable miCube, que en realidad es el cubo y que accedemos a su componente transform en la posición x,y ,z.Por último, solo tenemos que mostrar las variables dentro del Debug.Log. |
En la siguiente imagen te muestro cómo queda la ventana inspector y el resultado en consola:

Fig. 6.29
El componente de transformación de momento lo dejaremos aquí y lo retomaremos más adelante con ejemplos mucho más prácticos. Ahora vamos a ver cómo podemos acceder a otro tipo de componentes. Esta vez vamos a guardar la información en variables para mayor comodidad.
#3 Ahora, ¿cómo lo hacemos para acceder a los otros componentes? Por ejemplo, ¿cómo podemos acceder al collider del cubo y cambiarle el tamaño de su collider?

Fig. 6.30
Si te fijas en la imagen anterior verás que el cubo tiene un componente llamado Box Collider. Dentro de este componente tiene un parámetro llamado Size que es el encargado de darle un tamaño en los ejes x, y, z. Para poder guardar la información en una variable de este componente utilizamos un método llamado GetComponent que vas a ver en el script. Si lo deseas puedes acceder a este enlace para más información de este método:
https://docs.unity3d.com/es/current/ScriptReference/GameObject.GetComponent.html
Para la siguiente actividad elimina el script del GameObject vacío y crea uno nuevo con el nombre de ComponenteCollider.cs y agrégalo a este.
| using System.Collections;using System.Collections.Generic;using UnityEngine;public class ComponenteCollider : MonoBehaviour { |
| public GameObject miCube;public BoxCollider miCollider;void Start(){this.miCube = GameObject.Find(“Cube”);this.miCollider = this.miCube.GetComponent<BoxCollider>();this.miCollider.size = new Vector3 (5f,5f,5f);}} |
| Primero debemos crear una variable pública de tipo GameObject para contener al cubo que he llamado miCubo y luego necesitamos un contenedor de tipo BoxCollider para almacenar la información del Collider del cubo.Dentro de Start primero vamos a buscar el objeto cube; que en este caso como solo hay un cubo podemos utilizar el método Find con el nombre “Cube”.Ahora ya tenemos el cubo dentro de una variable pero todavía no podemos acceder a su componente BoxCollider, primero debemos obtener acceso y es por ese motivo que hemos creado la variable miCollider. Para tener permiso utilizamos el método GetComponentseguido del tipo entre <> y acabamos con();Ahora la variable miCollider puede acceder a las características del componente BoxCollider y podemos definir un tamaño.El tamaño necesita tres parámetros o valores decimales y por eso hemos creado un Vector3. Si no comprender muy bien que es no pasa nada porque lo veremos en otro tema.Si todo ha salido bien deberías ver como el collider del cubo se hace 5 unidades más grande. |
En la imagen siguiente te muestro cómo ya hemos hecho en los ejemplos anteriores, cómo accedemos a un objeto externo y a su componente desde el script del GameObject vacío. La variable pública MiCube de tipo GameObject toma de referencia el Objeto Cube de la escena y la variable pública MiCollider de tipo BoxCollider toma de referencia del BoxCollider del objeto Cube.

Fig. 6.31
Con el juego en ejecución podrás ver, si seleccionas el cubo, cómo su componente Collider tiene un tamaño de 5 unidades para todos sus ejes como te muestro en la siguiente imagen:

Fig. 6.32
Hasta ahora hemos demostrado que con un script podemos tener acceso a los objetos y a sus componentes, tanto al propio objeto que tiene el script como a un objeto externo. En el próximo apartado vamos a ver en mayor detalle el componente de transformación.
4. Entender las transformaciones
Ya sabemos cómo podemos acceder a gameObjects y a sus componentes, es lo que necesitamos para empezar a trabajar con las transformaciones.
En el inspector de Unity tenemos tres opciones de transformación que son posición, rotación y escalado. Estas tres opciones se caracterizan por un vector3 en cada una de sus transformaciones. Un vector 3 se caracteriza por un valor en x,y,z. Estos valores son coordenadas que nos permiten posicionar, rotar o escalar un objeto.
Si queremos empezar mover nuestros objetos vamos a tener que entender que es un Vector3.

Fig. 6.33
En el inspector de Unity tenemos tres opciones de transformación que son posición, rotación y escalado. Estas tres opciones se caracterizan por un vector3 en cada una de sus transformaciones. Un vector 3 se caracteriza por un valor en x, y, z. Estos valores son coordenadas que nos permiten posicionar, rotar o escalar un objeto.
Puedes mirar la documentación referente a la clase Transform accediendo al siguiente enlace:
https://docs.unity3d.com/540/Documentation/ScriptReference/Transform.html
Para empezar a ver cómo funciona vamos a crear una nueva escena con el nombre Escena3. Guárdala en la carpeta Escenas como hemos hecho desde el comienzo del capítulo. Los objetos que vamos a utilizar son un cubo y una esfera, arrastra estos objetos de los Prefabs o si lo prefieres puedes crear los objetos tú mismo. En el caso de que crees los objetos desde el menú principal accediendo a GameObject > 3D Object > Cube u otro tipo de objeto, puedes utilizar los materiales que dispones en la carpeta Materiales en la ventana Project. Para diferenciar estos objetos vamos a ponerles nombres según el color que tienen; en el caso del ejemplo que voy a mostrar el cubo tendrá el nombre Verde y la esfera tendrá el nombre Amarillo, como te muestro en la siguiente imagen:
Бесплатный фрагмент закончился.
