Compartir a través de


Unity

Desarrollo de su primer juego con Unity y C#

Adam Tuliper

Descargar el código de muestra

Como arquitecto de software, he escrito muchos sistemas, he hecho ingeniería inversa en malware y código nativo y, en general, he sabido resolver los códigos. Pero cuando de hacer juegos se trata, no he sabido por dónde empezar. En las primeras épocas de Windows, me encargué de la programación de gráficos de código nativo, pero no fue una experiencia divertida. Luego comencé con el desarrollo en DirectX, pero me di cuenta de que, si bien era sumamente eficaz, me pareció que era demasiado código para lo que yo quería.

Entonces, un día decidí experimentar con Unity y vi que se podían hacer algunas cosas fascinantes. Este es el primer artículo de una serie que consta de cuatro partes, donde hablaré sobre los aspectos básicos y la arquitectura de Unity. Mostraré cómo crear juegos 2D y 3D y, por último, cómo compilar para las plataformas Windows.

Qué es Unity

Unity es un motor y marco 2D/3D que le brinda un sistema para diseñar escenas de juegos o de aplicaciones para 2D, 2.5D y 3D. Digo juegos y aplicaciones porque he visto no solo juegos, sino simuladores de aprendizaje, aplicaciones para socorristas y otras aplicaciones comerciales desarrolladas con Unity que tienen que interactuar con el espacio 2D/3D. Unity le permite interactuar con ellas no solo a través del código, sino también mediante componentes visuales, y exportarlos a cualquiera de las principales plataformas móviles y mucho más… gratis. (También hay una versión profesional que está muy bien, pero no es gratuita. Es impresionante lo que se puede hacer con la versión gratuita). Unity admite todas las aplicaciones 3D principales y muchos formatos de audio, incluso comprende el formato .psd de Photoshop, así que es posible soltar un archivo .psd en un proyecto de Unity. Unity le permite importar y ensamblar activos, escribir código para interactuar con objetos, crear animaciones o importarlas para usarlas con un sistema avanzado de animación y mucho más.

Como lo muestra la Figura 1, Unity se ha asegurado la compatibilidad entre plataformas, y es posible cambiar de plataforma con un solo clic, literalmente. Aunque, para ser francos, normalmente exige un esfuerzo mínimo, como la integración con cada tienda para las compras integradas.

Plataformas compatibles con Unity
Figura 1 Plataformas compatibles con Unity

Tal vez la parte más eficaz de Unity sea Asset Store de Unity, supuestamente el mejor lugar de compra de activos para el mercado de los juegos. Allí se puede encontrar todo para sus necesidades de componentes para juegos, como material gráfico, modelos 3D, archivos de animación para los modelos 3D (vea el contenido de Mixamo en la tienda para más de 10.000 movimientos), efectos de audio y pistas completas, complementos, incluidos algunos como el kit de herramientas MultiPlatform, que puede ayudar con la compatibilidad para varias plataformas, sistemas de scripting visual, como PlayMaker y Behave, sombreadores avanzados, texturas, efectos de partículas, etc. La interfaz de Unity permite ejecutar scripts en su totalidad, lo que permite integrar complementos de terceros directamente en la GUI de Unity. Además, como si fuera poco, los desarrolladores profesionales de juegos usan varios paquetes de la tienda de activos y, si tiene algo decente que ofrecer, también lo puede publicar.

Qué no es Unity

Dudo cuando tengo que describir algo que Unity no sea, porque la gente lo refuta todo el tiempo. Sin embargo, de manera predeterminada Unity no es un sistema en el que pueda diseñar sus activos 2D y modelos 3D (excepto por los terrenos). Puede traer un montón de zombies a escena y controlarlos, pero no podría crear los zombies con las herramientas predeterminadas de Unity. En este sentido, Unity no es una herramienta de creación de activos, como Autodesk Maya o 3DSMax, Blender o incluso Adobe Photoshop. No obstante, hay, al menos un complemento de modelado de un tercero (ProBuilder) que le permite modelar componentes 3D directamente desde Unity; hay complementos de creación de mundos 2D, como 2D Terrain Editor para crear entornos 2D en mosaicos; también puede diseñar terrenos desde Unity con las herramientas de terreno para crear paisajes sorprendentes con árboles, césped, montañas, etc. Por tato, una vez más, dudo al tener que decir los límites hasta donde llega Unity.

¿Qué tiene que ver Microsoft con todo esto? Microsoft y Unity trabajan de forma conjunta para asegurar una excelente compatibilidad entre las plataformas Microsoft. Unity admite ejecutables Windows independientes, Windows Phone, aplicaciones de la Tienda Windows, Xbox 360 y Xbox One.

Introducción

Descargue la versión más reciente de Unity y reciba un mouse de dos botones con una rueda de desplazamiento. Hay un solo descargable con una licencia para modo gratuito o profesional. Para ver las diferencias entre las versiones, vea unity3d.com/unity/licenses. El Editor, que es la interfaz principal de Unity, se ejecuta en Windows (incluido Surface Pro), Linux y OS X.

En el próximo artículo voy a analizar el desarrollo real de juegos con Unity, pero primero voy a explorar la interfaz de Unity, la estructura de proyectos y su arquitectura.

Arquitectura y compilación

Unity es un motor de juegos basado en C++ nativo. El código se escribe en C#, JavaScript (UnityScript) o, con menor frecuencia, en Boo. El código, no el código del motor de Unity, se ejecuta en Mono o Microsoft .NET Framework, que se compila Just-in-Time (JIT) (excepto para iOS, que no permite el código JIT, y Mono lo compila en código nativo mediante Ahead-of-Time [AOT]).

Unity le permite probar el juego en IDE sin tener que realizar ningún tipo de exportación o compilación. Cuando ejecuta el código en Unity, usa Mono versión 3.5, que tiene una compatibilidad con la API casi similar a la de .NET Framework 3.5/CLR 2.0.

Para editar el código en Unity, hacer doble clic en el archivo de código en la vista del proyecto, que abre el editor entre plataformas predeterminado, Mono­Develop. Si lo prefiere, puede configurar Visual Studio como editor.

La depuración es con MonoDevelop o un complemento de otro fabricante para Visual Studio, UnityVS. No es posible usar Visual Studio como depurador sin UnityVS porque al depurar el juego, no depura Unity.exe, depura un entorno virtual dentro de Unity con un Soft Debugger que emite comandos y realiza acciones.

Para depurar, inicie MonoDevelop desde Unity. MonoDevelop tiene un complemento que abre una conexión de vuelta con el depurador de Unity y emite comandos después del procedimiento Debug | Attach to Process en MonoDevelop. Con UnityVS, conecta el depurador de Visual Studio nuevamente a Unity.

Cuando abre Unity por primera vez, ve el cuadro de diálogo del proyecto que aparece en la Figura 2.

El asistente de proyectos de Unity
Figura 2 El asistente de proyectos de Unity

En el cuadro de diálogo, especifica el nombre y la ubicación del proyecto (1). Puede importar los paquetes al proyecto (2), aunque no tiene que marcar nada aquí; la lista se proporciona para su conveniencia únicamente. También puede importar un paquete más adelante. Un paquete es un archivo .unitypackage que contiene recursos preempaquetados: modelos, código, escenas, complementos, cualquier cosa en Unity que pueda empacar; y puede reutilizarlos o distribuirlos con facilidad. No marque nada aquí si no sabe qué es, el tamaño del proyecto puede crecer, en ocasiones, muchísimo. Finalmente, puede elegir 2D o 3D (3). Esta lista desplegable es relativamente nueva en Unity, que no tenía grandes herramientas para juegos 2D hasta hace relativamente poco. Cuando se establece en 3D, los valores predeterminados se relacionan con un proyecto 3D, el comportamiento habitual de Unity durante años, así que no voy a hacer una mención especial. Cuando se escoge 2D, Unity cambia algunas cosas que parecen pequeñas, pero que son importantes; sobre estas voy a hablar en un artículo posterior sobre 2D en esta serie.

Esta lista se completa a partir de los archivos .unitypackage que se encuentran en ciertas ubicaciones del sistema; Unity ofrece varias en la instalación. Todo lo que descargue de la tienda de activos de Unity viene como archivo .unitypackage y se almacena localmente en el sistema en C:\Usuarios\<usted>\AppData\­Roaming\Unity\Asset Store. Por lo tanto, aparecerá en la lista una vez que exista en su sistema. Puede hacer doble clic en cualquier archivo .unitypackage, y se importará al proyecto.

Para seguir con la interfaz de Unity, voy a continuar desde que se hace clic en Create en el cuadro de diálogo en Figura 2 para crear un nuevo proyecto. En la Figura 3 se muestra el diseño de pantalla predeterminado de Unity.

La ventana predeterminada de Unity
Figura 3 La ventana predeterminada de Unity

Esto es lo que se ve:

  1. Project: todos los archivos del proyecto. Puede arrastrar desde el Explorador y colocar en Unity para agregar archivos a su proyecto.
  2. Scene: La escena abierta actualmente.
  3. Hierarchy: Todos los objetos del juego en la escena. Tenga en cuenta el uso del término GameObjects y del menú desplegable GameObjects.
  4. Inspector: Los componentes (propiedades) del objeto seleccionado en la escena.
  5. Toolbar: A la izquierda, se encuentran Pan, Move, Rotate, Scale y, en el centro, Play, Pause, Advance Frame. Si hace clic en Play, se reproduce el juego casi al instante, sin necesidad de compilaciones independientes. Pause pone el juego en pausa y Advance Frame lo ejecuta un fotograma a la vez, lo que le ofrece un enorme control de depuración.
  6. Console: Esta ventana puede quedar algo oculta, pero muestra los resultados de la compilación, los errores, las advertencias, etc. También muestra los mensajes de depuración del código; por ejemplo, Debug.Log muestra aquí su resultado.

Es importante mencionar la pestaña Game junto a la pestaña Scene. Esta pestaña se activa cuando hace clic en Play y el juego comienza a ejecutarse en esta ventana. Este es el llamado “modo de juego” y le da un marco para probar el juego, incluso le permite hacer cambios en directo en el juego si vuelve a la pestaña Scene. Aunque tenga cuidado con esto. Mientras el botón Play esté resaltado, se encontrará en el modo de juego y cuando lo abandone, se perderán los cambios introducidos durante el modo de juego. Yo, además de todos los desarrolladores de Unity con los que he hablado, hemos perdido trabajo de este modo, así que cambié el color de mi editor para que fuera evidente cuando me encontrara en el modo de juego; esto se puede hacer desde Edit | Preferences | Colors | Playmode tint.

Acerca de las escenas

Todo lo que se ejecuta en el juego existe en una escena. Cuando empaqueta el juego para una plataforma, el juego resultante es una colección de una o más escenas, además del código dependiente de la plataforma que agregue. En un proyecto, puede tener tantas escenas como quiera. Una escena puede pensarse como un nivel de un juego, aunque puede tener varios niveles en un archivo de escena si mueve el jugador o la cámara a distintos puntos de la escena. Cuando descarga los paquetes de terceros o incluso juegos de muestra de la tienda de activos, normalmente debe buscar los archivos de escenas de su proyecto que quiere abrir. Un archivo de escena es un archivo único que contiene todo tipo de metadatos sobre los recursos usados en un proyecto para la escena actual y sus propiedades. Es importante guardar una escena a menudo con Ctrl+S durante el desarrollo, al igual que con cualquier otra herramienta.

En general, Unity abre la última escena en la que trabajó, aunque a veces, cuando Unity bare un proyecto, crea una nueva escena vacía y usted tiene que buscar la escena en el explorador de proyectos. Esto puede ser un poco confuso para los nuevos usuarios, pero es importante recordarlo si abre su último proyecto y se pregunta adónde fue a parar todo el trabajo. No se preocupe, encontrará el trabajo en un archivo de escena que guardó en su proyecto. Para buscar todas las escenas de su proyecto, puede hacer clic en el icono que se indica en la Figura 4 y filtrar por Scene.

Filtrar escenas en el proyecto
Figura 4 Filtrar escenas en el proyecto

En una escena, no puede ver nada sin una cámara y no puede oír nada sin un componente Audio Listener adjunto a algún GameObject. No obstante, tenga en cuenta que en cualquier nueva escena, Unity siempre crea una cámara que ya tiene un componente Audio Listener.

Estructura del proyecto e importación de activos

Los proyectos de Unity no son como los proyectos de Visual Studio. No abre un archivo del proyecto, ni siquiera un archivo de la solución, porque no existe. Apunta Unity a una estructura de carpetas y abre la carpeta como proyecto. Los proyectos contienen carpetas Assets, Library, ProjectSettings y Temp, pero la única carpeta que aparece en la interfaz es Assets, que puede ver en la Figura 4.

La carpeta Assets contiene todos sus activos: material gráfico, código, audio; cada archivo que incluya en su proyecto va aquí. Esta es siempre la carpeta de nivel superior de Unity Editor. Pero haga los cambios solo en la interfaz de Unity, nunca a través del sistema de archivos.

La carpeta Library es la caché local para los activos importados; mantiene todos los metadatos de los activos. La carpeta ProjectSettings almacena las opciones que configure desde Edit | Project Settings. La carpeta Temp se usa para los archivos temporales de Mono y Unity durante el proceso de compilación.

Quiero destacar la importancia de hacer los cambios solo a través de la interfaz de Unity y no en el sistema de archivos directamente. Esto incluye las sencillas operaciones de copiar y pegar. Unity hace un seguimiento de los metadatos a través del editor, así que use el editor para realizar los cambios (a excepción de algunos casos marginales). Aunque puede arrastrar elementos desde el sistema de archivos y colocarlos en Unity, eso sí es posible.

El omnipresente GameObject

Casi todo en una escena es un GameObject. Piense en System.Object en .NET Framework. Casi todos los tipos provienen de él. El mismo concepto se aplica a GameObject. Es la clase básica para todos los objetos en su escena de Unity. Todos los objetos que aparecen en la Figura 5 (y muchos más) provienen de un GameObject.

GameObjects en Unity
Figura 5 GameObjects en Unity

Un GameObject es bastante sencillo, ya que pertenece a la ventana Inspector. En la Figura 6 puede ver que se agregó un GameObject vacío a la escena; observe las propiedades en Inspector. De forma predeterminada, GameObjects no tienen propiedades visuales, excepto por el widget que muestra Unity cuando resalta el objeto. En este punto, es un objeto bastante vacío.

Un GameObject sencillo
Figura 6 Un GameObject sencillo

Un GameObject tiene las propiedades Name, Tag (similar a una etiqueta de texto que asignaría mediante una FrameworkElement.Tag en XAML o una etiqueta en Windows Forms), Layer y Transform (tal vez la propiedad más importantes de todas).

La propiedad Transform es sencillamente la posición, rotación y escala de un GameObject. Unity usa el sistema de coordenadas a la izquierda, en el que piensa las coordenadas de la pantalla del ordenador como X (horizontal), Y (vertical) y Z (profundidad, es decir, entrando o saliendo de la pantalla).

En el desarrollo de juegos, es bastante común el uso de vectores, de los que hablaré un poco más en los artículos próximos. Por ahora, alcanza con saber que Transform.Position y Transform.Scale son ambos objetos Vector3. Un Vector3 es simplemente un vector tridimensional; en otras palabras, no son más que tres puntos: tan solo X, Y y Z. Mediante estos tres sencillos valores, puede definir la ubicación de un objeto e incluso mover un objeto en la dirección de un vector.

Componentes

Al agregar componentes, agrega funcionalidad a los GameObjects. Todo lo que agrega es un componente y todos aparecen en la ventana Inspector. Existen componentes MeshRender y SpriteRender; componentes para la funcionalidad de audio y cámara; componentes relacionados con la física (colisionadores y cuerpos rígidos), sistemas de partículas, sistemas de búsqueda de ruta, componentes personalizados de terceros, etc. Use un componente de script para asignar código a un objeto. Los componentes son los que hacen que los GameObjects cobren vida ya que agregan funcionalidad, es semejante al patrón de decorador en el desarrollo de software, aunque mucho mejor.

Voy a asignar algo de código a un nuevo GameObject, en este caso, es un cubo sencillo que se puede crear desde GameObject | Create Other | Cube. Le puse el nombre Enemy al cubo y luego creé otro para tener dos cubos. En la Figura 7, puede ver que moví un cubo a unas -15 unidades del otro, lo que se puede hacer con la herramienta de movimiento de la barra de herramientas o la tecla W una vez que el objeto está resaltado.

Proyecto actual con dos cubos
Figura 7 Proyecto actual con dos cubos

El código es una clase sencilla que busca un jugador y mueve su dueño hacia él. Normalmente, las operaciones de movimiento se pueden completar mediante uno de dos métodos: Mueve un objeto a una nueva posición en cada fotograma al cambiar sus propiedades Transform.Position, o puede aplicar una fuerza física y dejar que Unity se encargue del resto.

Los movimientos por fotograma involucran una forma de pensar un tanto distinta de “mover hasta este punto”. En este ejemplo, voy a mover el objeto un poco en cada fotograma para tener un control exacto de hacia dónde se mueve. Si prefiere no ajustar cada fotograma, existen bibliotecas para los movimientos de llamada de función simple, como la biblioteca gratuita iTween.

Lo primero que hago es hacer clic con el botón secundario en la ventana Project para crear un nuevo script de C# llamado EnemyAI. Para asignar este script a un objeto, simplemente arrastro el archivo de script desde la vista del proyecto hasta el objeto en la vista Scene o Hierarchy, y el código se asigna al objeto. Unity se encarga del resto. Así de fácil.

La Figura 8 muestra el cubo Enemy con el script asignado.

Enemy con un script asignado
Figura 8 Enemy con un script asignado

Eche un vistazo al código de la Figura 9 y observe la variable pública. Si mira en el editor, puede ver que mi variable pública aparece con una opción para anular los valores predeterminados en tiempo de ejecución. Esto es bastante genial. Puede cambiar los valores predeterminados de la GUI para tipos primitivos y también puede exponer las variables públicas (aunque no las propiedades) de muchos tipos de objeto diferentes. Si arrastro este código y lo coloco en otro GameObject, se crea una instancia totalmente independiente de ese componente de código. Este es un ejemplo básico y se puede hacer más eficaz si, por ejemplo, se agrega un componente RigidBody a este objeto, pero por ahora no voy a complicarlo.

Figura 9 El script de EnemyAI

public class EnemyAI : MonoBehavior
{
  // These values will appear in the editor, full properties will not.
  public float Speed = 50;
  private Transform _playerTransform;
  private Transform _ myTransform;
  // Called on startup of the GameObject it's assigned to.
  void Start()
  {
    // Find some gameobject that has the text tag "Player" assigned to it.
    // This is startup code, shouldn't query the player object every
    // frame. Store a ref to it.
    var player = GameObject.FindGameObjectWithTag("Player");
    if (!player)
    {
      Debug.LogError(
        "Could not find the main player. Ensure it has the player tag set.");
    }
    else
    {
      // Grab a reference to its transform for use later (saves on managed
      // code to native code calls).
      _playerTransform = player.transform;
    }
    // Grab a reference to our transform for use later.
    _myTransform = this.transform;
  }
  // Called every frame. The frame rate varies every second.
  void Update()
  {
    // I am setting how fast I should move toward the "player"
    // per second. In Unity, one unit is a meter.
    // Time.deltaTime gives the amount of time since the last frame.
    // If you're running 60 FPS (frames per second) this is 1/60 = 0.0167,
    // so w/Speed=2 and frame rate of 60 FPS (frame rate always varies
     // per second), I have a movement amount of 2*0.0167 = .033 units
    // per frame. This is 2 units.
    var moveAmount = Speed * Time.deltaTime;
    // Update the position, move toward the player's position by moveAmount.
    _myTransform.position = Vector3.MoveTowards(_myTransform.position,
      _playerTransform.position, moveAmount);
  }
}

En el código, puedo obtener una referencia a mi componente expuesto en el editor. También puedo asignar scripts a un GameObject, cada uno con sus propios métodos Start y Update (y muchos otros métodos). Suponiendo que un componente de script que contiene este código necesita una referencia a la clase (componente) EnemyAI, sencillamente puedo pedir ese componente:

public class EnemyHealth : MonoBehavior
private EnemyAI _enemyAI;
// Use this for initialization.
void Start () {
  // Get a ref to the EnemyAI script component on this game object.
  var enemyAI = this.GetComponent<EnemyAI>();
}
// Update is called once per frame.
void Update () {
  _enemyAI.MoveTowardsPlayer();
}

Después de editar el código en MonoDevelop o el editor de código de su elección y volver a Unity, observará una leve demora. Esto se debe a que Unity está compilando el código en segundo plano. Para cambiar el editor de código (no el depurador), vaya a Edit | Preferences | External Tools | External Script Editor. Los problemas de compilación aparecerán en la barra inferior de estado de la pantalla Editor de Unity, así que présteles atención. Si intenta ejecutar el juego con errores en el código, Unity no le dejará continuar.

Escritura de código

En el ejemplo de código anterior, hay dos métodos, Start y Update, y la clase EnemyHealth hereda de la clase básica MonoBehavior, que le permite asignar esa clase a un GameObject. Esa clase básica presenta una amplia variedad de funcionalidades y, en general, algunos métodos y propiedades. Los métodos principales son aquellos a los que Unity llamará si existen en su clase. Hay varios métodos a los que se puede llamar (vea bit.ly/1jeA3UM). Si bien existen muchos métodos, al igual que con ASP.NET Web Forms Page Lifecycle, en general usará solo unos pocos. Aquí encontrará los métodos de código más comunes que implementará en sus clases, que se relacionan con la secuencia de eventos para la clase derivada de MonoBehavior:

Awake: Se llama a este método una vez por objeto cuando el objeto se inicializa por primera vez. Puede que otros componentes no se hayan inicializado, así que este método se usa normalmente para inicializar el GameObject actual. Debe usar siempre este método para inicializar una clase derivada de MonoBehavior, no un constructor. Y no intente consultar otros objetos de su escena aquí, ya que puede que no se hayan inicializado.

Start: Se llama a este método durante el primer fotograma de la vida del objeto, pero antes de cualquier método Update. Puede verse como algo muy similar a Awake, pero con Start sabe que los demás objetos se han inicializado mediante Awake y existen en su escenario y, por lo tanto, puede consultar otros objetos del código fácilmente, por ejemplo:

// Returns the first EnemyAI script component instance it finds on any game object.
// This type is EnemyAI (a component), not a GameObject.
var enemyAI = GameObject.FindObjectOfType<EnemyAI>();
// I'll actually get a ref to its top-level GameObject.
var enemyGameObject = enemyAI.gameObject;
// Want the enemy’s position?
var position = enemyGameObject.transform.position;

Update: Se llama a este método en cada fotograma. Se podrá preguntar con qué frecuencia. Bueno, varía. Depende completamente de los cálculos. Dado que el sistema siempre cambia la carga a medida que representa distintas cosas, esta velocidad de fotogramas cambia a cada segundo. Puede presionar el botón Stats de la pestaña Game cuando esté en modo de juego para ver la velocidad de fotogramas actual, como se ve en la Figura 10.

Estadísticas
Figura 10 Estadísticas

FixedUpdate: Se llama a este método un número fijo de veces por segundo, independientemente de la velocidad de fotogramas. Dado que se llama a Update una cantidad variable de veces por segundo y no está sincronizado con el motor de física, suele ser mejor usar FixedUpdate cuando quiere aplicar una fuerza o alguna otra función relacionada con la física sobre un objeto. De forma predeterminada, se llama a FixedUpdate cada 0,02 segundos, es decir, que Unity también realiza cálculos físicos cada 0,02 segundos (este intervalo se llama Fixed Timestep y el desarrollador puede ajustarlo), lo que, nuevamente, es independiente de la velocidad de fotogramas.

Proyectos de código generado por Unity

Una vez que tiene el código en su proyecto, Unity crea uno o más archivos del proyecto en la carpeta raíz (que no se ve desde la interfaz de Unity). Estos no son los binarios del motor de Unity, sino los proyectos para Visual Studio o MonoDevelop en los que modificará y compilará el código. Unity puede crear lo que se parecería a un montón de objetos independientes, como lo muestra la Figura 11, aunque cada uno tenga un propósito importante.

Proyectos creados en Unity
Figura 11 Proyectos creados en Unity

Si tiene un proyecto de Unity sencillo, no verá todos estos archivos. Se crean solo cuando ha puesto código en varias carpetas especiales. Los proyectos que se muestran en la Figura 11 están desglosados por tres tipos únicamente:

  • Assembly-CSharp.csproj
  • Assembly-CSharp-Editor.csproj
  • Assembly-CSharp-firstpass.csproj

Para cada uno de estos proyectos, existe un proyecto duplicado creado con -vs al final, Assembly-CSharp-vs.csproj, por ejemplo. Estos proyectos se usan si usa Visual Studio como editor de código, y se pueden agregar al proyecto exportado desde Unity para la depuración específica para la plataforma en su solución de Visual Studio.

Los otros proyectos tienen el mismo propósito, pero CSharp se reemplaza por UnityScript. Estas son sencillamente las versiones JavaScript (UnityScript) de los proyectos, que existirán únicamente si usa JavaScript en su juego de Unity y solo si conserva los scripts en las carpetas que activan estos proyectos que se van a crear.

Ahora que ha visto qué proyectos se crean, voy a explorar las carpetas que activan estos proyectos y le muestran cuáles son sus propósitos. Cada ruta de carpeta supone que está debajo de la carpeta raíz /Assets en la vista del proyecto. Assets es siempre la carpeta raíz y contiene todos los archivos de activos debajo de ella. Por ejemplo, Standard Assets es, en realidad, /Assets/Standard Assets. El proceso de compilación de sus scripts se ejecuta a través de cuatro fases para generar ensamblados. Los objetos compilados en la fase 1 no pueden ver aquellos de la fase 2 ya que no se han compilado aún. Es importante saber esto cuando mezcla UnityScript y C# en el mismo proyecto. Si quiere hacer referencia a una clase de C# desde UnityScript, debe asegurarse de que se compile en una fase anterior.

La fase 1 consta de scripts en tiempo de ejecución en las carpetas Standard Assets, Pro Standard Assets y Plug-ins, todas ubicadas debajo de /Assets. Esta fase crea el proyecto Assembly-CSharp-firstpass.csproj.

Los scripts de la fase 2 se encuentran en las carpetas Standard Assets/Editor, Pro Standard Assets/Editor y Plug-ins/Editor. La última carpeta está destinada a los scripts que interactúan con la API del Unity Editor para la funcionalidad en tiempo de diseño (piense en un complemento de Visual Studio y cómo mejora la GUI, solo que esta se ejecuta en el Unity Editor). Esta fase crea el proyecto Assembly-CSharp-Editor-firstpass.csproj.

La fase 3 comprende todos los otros scripts que no están dentro de la carpeta Editor. Esta fase crea el proyecto Assembly-CSharp-Editor.csproj.

La fase 4 consta de todos los scripts restantes (aquellos dentro de cualquier otra carpeta llamada Editor, como /Assets/Editor o /Assets/­Foo/Editor). Esta fase crea el proyecto Assembly-CSharp.csproj.

Existe otro par de carpetas menos usadas y que no analizaremos aquí, como Resources. Y queda pendiente la pregunta de qué usa el compilador. ¿Es .NET? ¿Es Mono? ¿Es .NET para Windows en tiempo de ejecución (WinRT)? ¿Es .NET para Windows Phone en tiempo de ejecución? La Figura 12 enumera los valores predeterminados usados para la compilación. Es importante saber esto, en particular para las aplicaciones basadas en WinRT, ya que las API disponibles por plataforma varían.

Figura 12 Variaciones de compilación

Plataforma Ensamblados de juegos generados por Compilación final realizada por
Windows Phone 8 Mono Visual Studio/.NET
Tienda Windows .NET Visual Studio/.NET (WinRT)
Windows independiente (.exe) Mono Unity genera .exe + libs
Windows Phone 8,1 .NET Visual Studio/.NET (WinRT)

Cuando compila para Windows, Unity es responsable de hacer las llamadas para generar las bibliotecas de juegos desde su código C#/UnityScript/Boo (DLL) e incluir las bibliotecas nativas en tiempo de ejecución. Para la Tienda Windows y Windows Phone 8, exportará una solución en Visual Studio, excepto para Windows independiente, en la que Unity genera los archivos .exe y los .dll obligatorios. Voy a analizar los distintos tipos de compilación en el artículo final de la serie, donde hablaré sobre compilar para la plataforma. DirectX se encarga de la representación de gráficos a bajo nivel en las plataformas Windows.

Diseñar un juego en Unity es un proceso bastante directo:

  • Traer los activos (material gráfico, audio, etc.). Usar la tienda de activos. Escribir el resto. Contratar a un artista. Tenga en cuenta que Unity tiene compatibilidad nativa para Maya, Cheetah3d, Blender y 3dsMax, en algunos casos en los que se necesite instalar ese software para trabajar con formatos nativos 3D, y también funciona con los formatos de archivo comunes .obj y .fbx.
  • Escribir el código en C#, JavaScript/UnityScript o Boo para controlar los objetos, las escenas e implementar la lógica del juego.
  • Probar en Unity. Exportar a una plataforma.
  • Probar en esa plataforma. Implementar.

¡Pero, un momento… quiero más!

Este artículo tiene como fin servir de resumen de la arquitectura y el proceso en Unity. Analicé la interfaz, los aspectos básicos de asignar código, GameObjects, componentes, Mono y .NET, y más. Sirve de buena base para el siguiente artículo, donde voy a profundizar en el ensamblado de los componentes de un juego 2D. Siga atento a Microsoft Virtual Academy, ya que a finales de verano voy a presentarme en un evento de dos días sobre Unity. Y preste atención a los eventos regionales en unity3d.com/pages/windows/events.


Adam Tuliper es un evangelizador técnico sénior de Microsoft y vive en el soleado Sur de California. Es un devoto de los juegos independientes, coadministrador de Orange County Unity Meetup y autor de pluralsight.com. Él y su esposa están por tener su tercer hijo, así que puede comunicarse con él mientras aún tiene tiempo en adamt@microsoft.com o en Twitter en twitter.com/AdamTuliper.

Gracias a los siguientes expertos técnicos por revisar este artículo: Matt Newman (Subscience Studios), Jaime Rodriguez (Microsoft) y Tautvydas Žilys (Unity)