Unity

Desenvolvendo seu primeiro jogo com Unity e C#

Adam Tuliper

Baixar o código de exemplo

Como um arquiteto de software, eu criei muitos sistemas, malware de código nativo por engenharia inversa, e geralmente consegui descobrir coisas no lado dos códigos. Quando falamos sobre criar jogos, eu ficava um pouco perdido sobre onde começar. Eu tinha realizado alguma programação de gráfico de código nativo no início do Windows e não foi uma experiência divertida. Então, comecei com o desenvolvimento do DirectX e percebi que, embora seja extremamente poderoso, parecia muito código para o que eu desejava fazer.

Assim, um dia, eu decidi experimentar o Unity e vi que podia fazer coisas incríveis. Este é o primeiro artigo em uma série de quatro partes onde irei abordar os fundamentos e a arquitetura do Unity. Eu mostrarei como criar jogos 2D e 3D e, por fim, como compilar para plataformas Windows.

O que é o Unity

Unity é um mecanismo 2D/3D e estrutura que fornece um sistema para criar jogos e cenas de aplicativo para 2D, 2.5D e 3D. Eu digo jogos e aplicativos porque não vi apenas jogos, mas simuladores de treinamento, aplicativos de primeiros socorros e outros aplicativos focalizados em negócios desenvolvidos com o Unity que precisam interagir com o espaço 2D/3D. O Unity permite interagir com eles não apenas via código, mas também através de componentes visuais, e exportar para cada grande plataforma móvel e muitas mais—gratuitamente. (Há também uma versão profissional muito boa, mas não é gratuita. Você pode fazer uma quantidade impressionante com a versão gratuita.) O Unity suporta todos os principais aplicativos 3D e vários formatos de áudio e até compreende o formato .psd do Photoshop para que você possa apenas inserir um arquivo .psd em um projeto Unity. O Unity permite importar e montar ativos, gravar um código para interagir com seus objetos, criar ou importar animações para uso com um sistema de animação avançado e muito mais.

Como a Figura 1 indica, o Unity realizou trabalhos para garantir o suporte entre plataformas e você pode alterar as plataformas literalmente com um clique, embora para ser justo há apenas pouco esforço necessário, como a integração com cada loja para compras de aplicativos.

Plataformas suportadas pelo Unity
Figura 1 Plataformas suportadas pelo Unity

Talvez a parte mais poderosa do Unity é o Unity Asset Store, sem dúvida o melhor mercado de ativos em jogos. Nele você pode encontrar todas as suas necessidades de componentes de jogos, como arte, modelos 3D, arquivos de animação para seus modelos 3D (veja o conteúdo de Mixamo na loja para mais de 10.000 movimentos), efeitos de áudio e álbuns completos, plug-ins—incluindo aqueles como o kit de ferramentas MultiPlatform que ajudam com o suporte de múltiplas plataformas—sistemas de script visual como PlayMaker e Behave, sombreadores avançados, texturas, efeitos de partículas e mais. A interface Unity é totalmente scriptável, permitindo que vários plug-ins de terceiros se integrem diretamente na GUI do Unity. A maioria, se não todos, os desenvolvedores de jogos profissionais usam vários pacotes da loja de ativos e se você tiver algo bom para oferecer, é possível publicar.

O que o Unity não é

Eu hesito em descrever algo que o Unity não é porque as pessoas duvidam disso todo o tempo. No entanto, o Unity por padrão não é um sistema no qual você deva projetar seus ativos 2D e modelos 3D (exceto para terrenos). É possível colocar vários zumbis em uma cena e controlá-los, mas não é possível criar zumbis na ferramenta padrão do Unity. Neste sentido, o Unity não é uma ferramenta de criação de ativos como o Autodesk Maya ou 3DSMax, Blender ou até mesmo Adobe Photoshop. Há pelo menos um plug-in de modelagem de terceiros (ProBuilder), que permite modelar componentes 3D diretamente dentro do Unity; há plug-ins construtores de mundos 2D como o 2D Terrain Editor para criar ambientes dinâmicos 2D e você também pode criar terrenos dentro do Unity usando as Terrain Tools para criar incríveis paisagens com árvores, grama, montanhas e mais. Novamente, eu hesito em sugerir qualquer limite sobre o que o Unity pode fazer.

Onde a Microsoft entra nisso? A Microsoft e o Unity trabalham em conjunto para garantir um ótimo suporte à plataforma em toda pilha Microsoft. O Unity suporta executáveis autônomos Windows, Windows Phone, aplicativos do Windows Store, Xbox 360 e Xbox One.

Introdução

Baixe a última versão do Unity e obtenha um mouse de dois botões com uma roda de rolagem clicável. Há apenas um único download que pode ser licenciado para o modo gratuito ou profissional. Você pode ver as diferenças entre as versões em unity3d.com/unity/licenses. O Editor, que é a principal interface do Unity, funciona no Windows (incluindo Surface Pro), Linux e OS X.

Irei comentar o desenvolvimento de jogos real com o Unity no próximo artigo, mas primeiro irei explorar a interface, a estrutura do projeto e a arquitetura do Unity.

Arquitetura e compilação

Unity é um mecanismo de jogos baseado em C++ nativo. Seu código de gravação no C#, JavaScript (UnityScript) ou, menos frequentemente, Boo. Seu código, não o código de mecanismo do Unity, funciona no Mono ou no Microsoft .NET Framework, que é compilado Just-in-Time (JIT) (exceto para o iOS, que não permite o código JIT e é compilado pelo Mono para o código nativo usando a compilação Ahead-of-Time [AOT]).

O Unity permite testar seu jogo no IDE sem precisar realizar qualquer tipo de exportação ou compilação. Ao executar o código no Unity, você está usando o Mono versão 3.5, que tem uma compatibilidade de API parecida com aquela do .NET Framework 3.5/CLR 2.0.

Você edita seu código no Unity clicando duas vezes em um arquivo de código na exibição do projeto, que abre o editor entre plataformas padrão, o Mono­Develop. Se você prefere, é possível configurar o Visual Studio como seu editor.

Você realiza a depuração com o MonoDevelop ou usa um plug-in de terceiros para o Visual Studio, UnityVS. Não é possível usar o Visual Studio como um depurador sem o UnityVS porque ao depurar seu jogo, você não está depurando o Unity.exe, está depurando um ambiente virtual dentro do Unity, usando um depurador simples que emitiu comandos e realizou ações.

Para depurar, você lança o MonoDevelop do Unity. O MonoDevelop tem um plug-in que abre uma conexão de volta ao depurador do Unity e emite comandos depois de Depurar | Anexar para processar no MonoDevelop. Com o UnityVS, você conecta o depurador do Visual Studio novamente no Unity.

Ao abrir o Unity pela primeira vez, você vê a caixa de diálogo do projeto mostrada na Figura 2.

O assistente de projeto do Unity

Figura 2 O assistente de projeto do Unity

Na caixa de diálogo do projeto, você especifica o nome e o local do seu projeto (1). É possível importar qualquer pacote no seu projeto (2), embora você não precise retirar nada daqui; a lista é fornecida apenas como uma conveniência. Também é possível importar um pacote posteriormente. Um pacote é um arquivo .unitypackage que contém recursos pré-embalados—modelos, código, cenas, plug-ins—tudo no Unity que você pode embalar—e pode reutilizar ou distribuir facilmente. Não retire algo se não souber o que é; o tamanho do seu projeto aumentará consideravelmente algumas vezes. Por fim, é possível selecionar 2D ou 3D (3). Este menu suspenso é relativamente novo no Unity, que não tem uma ferramenta de jogos 2D significativa até recentemente. Ao definir para 3D, os padrões favorecem um projeto 3D—geralmente o comportamento Unity conhecido por anos, portanto, não precisa de qualquer comentário especial. Quando o 2D é selecionado, o Unity altera algumas coisas aparentemente pequenas—mas importantes—que irei abordar no artigo 2D posteriormente nesta série.

Esta lista é preenchida pelos arquivos .unitypackage em determinados locais de seu sistema; o Unity fornece uma variedade na instalação. Tudo que você baixar da loja de ativos do Unity é fornecido também como um arquivo .unitypackage e é armazenado em cache localmente no sistema em C:\Usuários\<você>\AppData\­Roaming\Unity\Asset Store. Como tal, aparecerá nesta lista quando existir em seu sistema. Basta apenas clicar duas vezes em qualquer arquivo .unitypackage e ele seria importado pra seu projeto.

Continuando com a interface do Unity, você continuará clicando em Criar na caixa de diálogo da Figura 2 para que um novo projeto seja criado. O layout da janela do Unity padrão é mostrado na Figura 3.

A janela do Unity padrão
Figura 3 A janela do Unity padrão

Aqui está o que você verá:

  1. Projeto: Todos os arquivos em seu projeto. É possível arrastar e soltar do Explorer para o Unity para adicionar arquivos em seu projeto.
  2. Cena: A cena aberta atualmente.
  3. Hierarquia: Todos os objetos do jogo na cena. Observe o uso do termo GameObjects e o menu suspenso GameObjects.
  4. Inspetor: Os componentes (propriedades) do objeto selecionado na cena.
  5. Barra de ferramentas: Do lado esquerdo estão Panorâmica, Mover, Girar, Dimensionar e no centro estão Reproduzir, Pausar, Avançar Quadro. Clicar em Reproduzir reproduz o jogo quase instantaneamente sem precisar realizar compilações separadas. Pausar pausa o jogo e avançar quadro reproduz um quadro por vez, fornecendo um controle de depuração muito forte.
  6. Console: Esta janela pode se tornar um pouco oculta, mas mostra o resultado de sua compilação, erros, avisos e assim por diante. Também mostra mensagens de depuração do código; por exemplo, Debug.Log mostrará seu resultado aqui.

É importante mencionar a guia Jogos próxima a guia Cena. Esta guia é ativada ao clicar em reproduzir e seu jogo começar a funcionar nesta janela. Isso é chamado de modo de reprodução, fornece um plano de fundo para testar seu jogo e permite realizar mudanças imediatas no jogo voltando para a guia Cena. Tenha muito cuidado. Enquanto o botão de reprodução estiver destacado, você está no modo de reprodução. Quando sair, qualquer mudança realizada durante o modo de reprodução será perdida. Eu, assim como praticamente qualquer desenvolvedor do Unity que conversei, perdi trabalhos dessa forma. Portanto, mudei minha cor no Editor para tornar óbvio quando estiver no modo de reprodução através de Editar | Preferências | Cores | Cor do modo de reprodução.

Sobre as cenas

Tudo que funciona no seu jogo existe em uma cena. Ao embalar seu jogo para uma plataforma, o jogo resultante é um conjunto de uma ou mais cenas, além de qualquer código dependente de plataforma adicionado. Você pode ter quantas cenas desejar em um projeto. Uma cena pode ser pensada como um nível em um jogo, embora você possa ter vários níveis em um arquivo de cena apenas movendo o reprodutor/câmera para diferentes pontos na cena. Ao baixar pacotes de terceiros ou até mesmo jogos de amostra na loja de ativos, você geralmente deve procurar pelos arquivos de cena no seu projeto para abrir. Um arquivo de cena é um arquivo único que contém todo tipo de metadados sobre os recursos usados no projeto para a cena atual e suas propriedades. É importante salvar uma cena frequentemente pressionando Ctrl+S durante o desenvolvimento, assim como qualquer outra ferramenta. 

Geralmente, o Unity abre a última cena que você trabalhou, embora algumas vezes quando o Unity abre um projeto, cria uma nova cena vazia e você precisa encontrar a cena no seu explorador de projetos. Isso pode ser muito confuso para novos usuários, mas é importante lembrar se você abrir seu último projeto e perguntar onde foi parar seu trabalho! Relaxe, você encontrará o trabalho em um arquivo de cena salvo no seu projeto. É possível pesquisar todas as cenas no seu projeto clicando no ícone indicado na Figura 4 e filtrar na Cena.

Filtrar cenas no projeto
Figura 4 Filtrar cenas no projeto

Em uma cena, não é possível ver nada sem uma câmera e ouvir nada sem um componente de Audio Listener anexado a algum GameObject. No entanto, observe que em qualquer nova cena, o Unity sempre cria ua câmera que tem um componente Audio Listener nele.

Estrutura do projeto e importação de ativos

Projetos Unity não são como projetos do Visual Studio. Você não abre um arquivo de projeto ou até um arquivo de solução, porque não existe. Você aponta o Unity para uma estrutura de pasta e abre a pasta como um projeto. Os projetos contêm as pastas Ativos, Biblioteca, ProjectSettings e Temp, mas a única exibida na interface é a pasta Ativos, como você pode ver na Figura 4.

A pasta Ativos contém todos os seus ativos—arte, código, áudio; cada arquivo fornecido no seu projeto está aqui. Esta é sempre a pasta de nível superior no Unity Editor. Mas faça mudanças apenas na interface Unity, nunca através do sistema de arquivos.

A pasta Biblioteca é o cache local para ativos importados; mantém todos os metadados para ativos. A pasta ProjectSettings armazena configurações realizadas em Editar | Configurações do Projeto. A pasta Temp é usada para arquivos temporários de Mono e Unity durante o processo de compilação.

Pretendo ressaltar a importância de realizar mudanças apenas através da interface Unity e não pelo sistema de arquivos diretamente. Isso inclui até copiar e colar. O Unity rastreia metadados para seus objetos através do editor, portanto, use o editor para fazer mudanças (além de alguns casos). É possível arrastar e soltar do seu sistema de arquivos para o Unity. Isso também funciona bem.

O GameObject All-Important

Praticamente tudo na sua cena é um GameObject. Pense em System.Object no .NET Framework. Quase todos os tipos são derivados. O mesmo conceito ocorre para GameObject. É a classe base para todos os objetos na sua cena do Unity. Todos os objetos mostrados na Figura 5 (e muitos outros) são derivados de um GameObject.

GameObjects no Unity

Figura 5 GameObjects no Unity

Um GameObject é muito simples porque pertence à janela Inspector. Você pode ver na Figura 6 que um GameObject vazio foi adicionado à cena; observe suas propriedades no Inspector. O GameObjects por padrão não tem propriedades visuais exceto quando o widget Unity é exibido ao destacar o objeto. Neste ponto, é apenas um objeto vazio.

Um GameObject simples
Figura 6 Um GameObject simples

Um GameObject tem um Nome, uma Marcação (semelhante à marcação de texto atribuída por um FrameworkElement.Tag no XAML ou uma marcação no Windows Forms), uma Camada e a Transformação (provavelmente a propriedade mais importante de todas).

A propriedade Transform é apenas a posição, rotação e dimensionamento de qualquer GameObject. O Unity usa o sistema de coordenada esquerdo, no qual você pensa nas coordenadas da sua tela do computador como X (horizontal), Y (vertical) e Z (profundidade, isto é, entrando e saindo da tela).

No desenvolvimento de jogos, é muito comum usar vetores, sobre os quais falarei um pouco mais nos próximos artigos. No momento, é suficiente saber que Transform.Position e Transform.Scale são objetos Vector3. Um Vector3 é apenas um vetor tridimensional; em outras palavras, não é nada mais do que três pontos—apenas X, Y e Z. Através destes três valores simples, é possível definir o local de um objeto e mover um objeto na direção de um vetor.

Componentes

Você adiciona funcionalidade ao GameObjects adicionando Componentes. Tudo que você adiciona é um Componente e eles mostram tudo na janela Inspetor. Há componentes MeshRender e SpriteRende; Componentes para funcionalidade de áudio e câmera; Componentes relacionados à física (aceleradores e corpos rígidos), sistemas de partículas, sistemas de localização de caminho, Componentes personalizados de terceiros e mais. Você usa um script Componente par atribuir código a um objeto. Os Componentes que colocam seu GameObjects em vida adicionando funcionalidade, semelhante ao padrão thedecorator no desenvolvimento de software, apenas muito mais frio.

Eu irei atribuir algum código a um novo GameObject, neste caso, um cubo simples que você pode criar através de GameObject | Criar Outro | Cubo. Eu renomeei o cubo Enemy e criei outros dois cubos. Você pode ver na Figura 7 que movi um cubo cerca de -15 unidades de distância do outro, o que você pode fazer usando a ferramenta mover na barra de ferramentas ou a tecla W quando o objeto for destacado.

Projeto atual com dois cubos

Figura 7 Projeto atual com dois cubos

O código é uma classe simples que localiza um jogador e move seu proprietário para ele. Você geralmente realiza operações de movimento através de uma de duas abordagens: Você move um objeto para uma nova posição a cada quadro alterando suas propriedades Transform.Position ou aplica uma força física nele e deixa que o Unity cuide do resto.

Fazer as coisas por quadro envolve uma forma um pouco diferente de pensar do que dizer "mover para este ponto". Para este exemplo, irei mover o objeto um pouco a cada quadro para que eu tenha o controle exato sobre para onde ele se move. Se você prefere não ajustar cada quadro, há bibliotecas para fazer uma única função de chamada de movimentos, como a biblioteca gratuita iTween.

A primeira coisa a fazer é clicar com o botão direito do mouse na janela Project para criar um novo script C# chamado EnemyAl. Para atribuir este script a um objeto, eu apenas arrasto o arquivo de script da exibição do projeto para o objeto na exibição de Cena ou na Hierarquia e o código é atribuído ao objeto. O Unity cuida do resto. É muito fácil.

A Figura 8 mostra o cubo Enemy com o script atribuído.

O Enemy com um script atribuído
Figura 8 O Enemy com um script atribuído

Veja o código na Figura 9 e observe a variável pública. Se você olhar o Editor, é possível ver que minha variável pública aparece como uma opção para substituir os valores padrões no tempo de execução. Isso é muito legal. É possível alterar os padrões na GUI para tipos primitivos e também é possível expor variáveis públicas (não propriedades) de vários tipos de objetos diferentes. Se eu arrastar e soltar este código em outro GameObject, uma instância completamente separada desse componente de código é instanciada. Este é um exemplo básico e pode ser tornado mais eficiente, digamos, adicionando um componente RigidBody a este objeto. Mas irei manter simples.

Figura 9 O script EnemyAI

public class EnemyAI : MonoBehavior 
{ 
// Estes valores aparecerão no editor, as propriedades completas não. 
public float Speed = 50; 
private Transform _playerTransform; 
private Transform _ myTransform; 
// Chamado na inicialização do GameObject atribuído. 
void Start() 
{ 
// Localize algum gameobject com a marcação de texto "Player" atribuída. 
// Este é o código de inicialização, não deve consultar o objeto de reprodução a cada 
// quadro. Armazene uma referência. 
var player = GameObject.FindGameObjectWithTag("Player"); 
if (!player) 
{
 Debug.LogError( 
"Impossível localizar o reprodutor principal. Certifique-se de que tem a marcação de reprodutor definida."); 
} 
else 
{ 
// Obtenha uma referência para sua transformação para uso posterior (economize no código 
// gerenciado para chamadas de código nativo). 
_playerTransform = player.transform; 
} 
// Obtenha uma referência para nossa transformação para uso posterior. 
_myTransform = this.transform; } 
// Chamado a cada quadro. A taxa de quadros varia por segundo. 
void Update() 
{ 
// Estou configurando a rapidez que devo mover para o "jogador" 
// por segundo. No Unity, uma unidade é um metro. 
// Time.deltaTime fornece a quantidade de tempo deste o último quadro. 
// Se você estiver executando o 60 FPS (quadros por segundo) isto é 1/60 = 0.0167, 
// então w/Speed=2 e a taxa de quadro de 60 FPS (a taxa de quadro sempre varia 
// por segundo), eu tenho uma quantidade de movimento de 2*0.0167 = .033 unidades 
// por quadro. Isto é 2 unidades. 
var moveAmount = Speed * Time.deltaTime; 
// Atualize a posição, mova para a posição do jogador por moveAmount. 
_myTransform.position = Vector3.MoveTowards(_myTransform.position, _playerTransform.position, moveAmount); 
} 
}

No código, eu posso obter uma referência a qualquer componente exposto no editor. Eu também posso atribuir scripts para um GameObject, cada um com seus próprios métodos Start e Update (e vários outros métodos). Assumindo que um componente de script contendo este código precisa de uma referência para a classe EnemyAI (componente), eu posso simplesmente solicitar esse componente:

public class EnemyHealth : MonoBehavior
private EnemyAI _enemyAI;
// Use isto para inicialização.
void Start () {
  //Obter uma ref para o componente do script EnemyAI neste objeto de jogo.
  var enemyAI = this.GetComponent<EnemyAI>();
}
// A atualização é chamada uma vez por quadro.
void Update () {
  _enemyAI.MoveTowardsPlayer();
}

Depois de editar o código no MonoDevelop ou seu editor de código de escolha e alterar para o Unity, você observará normalmente um pequeno atraso. Isso ocorre porque o Unity está compilando no plano de fundo seu código. É possível alterar seu editor de códigos (não depurador) via Editar | Preferências | Ferramentas Externas | Editor de Script Externo. Qualquer problema de compilação será mostrado na parte inferior da barra de status da sua tela do Unity Editor, portanto, fique de olho. Se você tentar executar seu jogo com os erros no código, o Unity não permitirá continuar.

Escrever código

No exemplo de código anterior, há dois métodos, Start e Update, e a classe EnemyHealth herda da classe base MonoBehavior, que permite apenas atribuir essa classe para um GameObject. Há muita funcionalidade nessa classe base usada e geralmente alguns métodos e propriedades. Os principais métodos são aqueles que o Unity chamará se existirem na sua classe. Há vários métodos que podem ser chamados (consulte bit.ly/1jeA3UM). Embora haja vários métodos, assim como aqueles com o ASP.NET Web Forms Page Lifecycle, você geralmente usa apenas alguns. Aqui estão os métodos de código mais comuns para implementar em suas classes, relacionados à sequência de eventos para as classes derivadas do MonoBehavior:

Awake: Este método é chamado uma vez por objeto quando o objeto é inicializado pela primeira vez. Outros componentes podem ainda não serem inicializados, portanto, este método é geralmente usado para inicializar o GameObject atual. Você sempre deve tentar usar este método para inicializar uma classe derivada do MonoBehavior, não um construtor. E não tente consultar outros objetos na sua cena, pois eles ainda podem não ter sido inicializados.

Start: Este método é chamado durante o primeiro quadro do tempo de vida do objeto, mas antes de qualquer método Update. Pode ser muito semelhante ao Awake, mas com Start, você sabe que outros objetos foram inicializados via Awake e exige em sua cena e, portanto, você pode consultar outros objetos no código facilmente, como a seguir:

// Retorna a primeira instância do componente de script EnemyAI que localizar em qualquer objeto do jogo.
// Este tipo é EnemyAI (um componente), não um GameObject.
var enemyAI = GameObject.FindObjectOfType<EnemyAI>();
// Irei realmente obter uma referência para seu GameObject de nível superior.
var enemyGameObject = enemyAI.gameObject;
// Deseja a posição do inimigo?
var position = enemyGameObject.transform.position;

Atualização: Este método é chamado em cada quadro. Qual é essa frequência? Bem, varia. Depende completamente da computação. Como seu sistema está sempre mudando sua carga conforme renderiza diferentes coisas, esta taxa de quadro varia a cada segundo. É possível pressionar o botão Estatísticas na guia Jogo quando você entrar no modo de reprodução para ver sua taxa de quadros atual, como mostrado na Figura 10.

Obter estatísticas
Figura 10 Obter estatísticas

FixedUpdate: Este método é chamado um número de vezes fixo por segundo, independente da taxa de quadros. Como Update é chamado por diferentes números de vezes por segundo e não está em sincronia com o mecanismo de física, é geralmente melhor usar o FixedUpdate quando você deseja fornecer uma força ou alguma outra função relacionada à física em um objeto. FixedUpdate por padrão é chamado a cada 0,02 segundos, significando que o Unity também realiza cálculos de física a cada 0,02 segundos (este intervalo é chamado de Timestep Fixo e é ajustado pelo desenvolvedor), que novamente é independente da taxa de quadros.

Projetos de código gerado pelo Unity

Quando você tem códigos em seu projeto, o Unity cria um ou mais arquivos de projeto na sua pasta raiz (que não é visível na interface do Unity). Eles não são binários do mecanismo Unity, mas os projetos para o Visual Studio ou MonoDevelop no qual você irá editar e compilar seu código. O Unity pode criar o que pode parecer muito como projetos separados, como a Figura 11 mostra, embora cada um deles tem um objetivo importante.

Projetos criados pelo Unity
Figura 11 Projetos criados pelo Unity

Se você tem um projeto Unity simples, não verá todos os arquivos. Eles são criados apenas quando você tem um código colocado em várias pastas especiais. Os projetos mostrados na Figura 11 são divididos por apenas três tipos:

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

Para cada um destes projetos, há um projeto duplicado criado com -vs anexado a ele, Assembly-CSharp-vs.csproj, por exemplo. Estes projetos são usados se o Visual Studio é seu editor de código e eles podem ser adicionados ao seu projeto exportado do Unity para depuração específica da plataforma em sua solução do Visual Studio.

Os outros projetos têm o mesmo objetivo, mas tem CSharp substituído por UnityScript. Eles são apenas as versões JavaScript (UnityScript) dos projetos, que existirão apenas se você usar JavaScript no seu jogo Unity e apenas se você tiver seus scripts nas pastas que acionam estes projetos para serem criados.

Agora que você viu quais projetos são criados, irei explorar as pastas que acionam estes projetos e mostram seus objetivos. Cada caminho da pasta assume que está abaixo da pasta raiz /Assets na sua exibição do projeto. Os ativos são sempre a pasta raiz e contêm todos os seus arquivos de ativos. Por exemplo, Standard Assets é realmente /Assets/Standard Assets. O processo de compilação para seu script funciona através de quatro fases para gerar assemblies. Objetos compilados na Fase 1 não podem ver aqueles na Fase 2 porque eles ainda não foram compilados. É importante saber isso quando você está misturando UnityScript e C# no mesmo projeto. Se você deseja referenciar uma classe C# do UnityScript, é necessário garantir que compila em uma fase anterior.

A Fase 1 consiste de scripts do tempo de execução nas pastas Standard Assets, Pro Standard Assets e Plug-ins, todas localizadas em/Assets. Esta fase cria o projeto Assembly-CSharp-firstpass.csproj.

Os scripts da Fase 2 estão nas pastas Standard Assets/Editor, Pro Standard Assets/Editor e Plug-ins/Editor. A última página é destinada para scripts que interagem com o API do Unity Editor para funcionalidade do tempo de design (pensando em um plug-in do Visual Studio e como melhora o GUI, apenas isto é executado no Unity Editor). Esta fase cria o projeto Assembly-CSharp-Editor-firstpass.csproj.

A Fase 3 inclui todos os outros scripts que ainda não estão dentro de uma pasta do Editor. Esta fase cria o projeto Assembly-CSharp-Editor.csproj.

A Fase 4 consiste de todos os scripts restantes (aqueles dentro da pasta chamada Editor, como /Assets/Editor ou /Assets/­Foo/Editor). Esta fase cria o projeto Assembly-CSharp.csproj.

Há algumas outras pastas menos usadas que não são abordadas aqui, como Resources. E há a pergunta pendente do que o compilador está usando. É .NET? É Mono? É .NET para o Windows Runtime (WinRT)? É o .NET para Windows Phone Runtime? A Figura 12 lista os padrões usados para compilação. É importante saber isso, especialmente para aplicativos baseados em WinRT porque os APIs disponíveis por plataforma variam.

Figura 12 Variações de compilação

Plataforma Assemblies de jogos gerados por Compilação final realizada por
Windows Phone 8 Mono Visual Studio/.NET
Windows Store .NET Visual Studio/.NET (WinRT)
Windows Standalone (.exe) Mono Unity - gera .exe + libs
Windows Phone 8.1 .NET Visual Studio/.NET (WinRT)

Ao realizar uma compilação para Windows, o Unity é responsável por criar as chamadas para gerar as bibliotecas de jogo do seu código C#/UnityScript/Boo (DLLs) e para incluir suas bibliotecas do tempo de execução nativa. Para o Windows Store e Windows Phone 8, exportará uma solução do Visual Studio, exceto para o Windows autônomo, no qual o Unity gera os arquivos .exe e .dll exigidos. Irei discutir os vários tipos de compilação no artigo final da série, quando abordar a criação da plataforma. A renderização de gráficos a um baixo nível é realizada nas plataformas do Windows pelo DirectX.

Criar um jogo no Unity é um processo bastante simples:

  • Traga seus ativos (arte, áudio e assim por diante). Use o repositório de ativos. Crie seu próprio. Contrate um artista. Observe que o Unity tem um suporte nativo para Maya, Cheetah3d, Blender e 3dsMax, em alguns casos exige que o software seja instalado para funcionar com estes formatos 3D nativos, e também funciona com formatos de arquivos comuns .obj e .fbx.
  • Redigir o código em C#, JavaScript/UnityScript ou Boo para controlar seus objetos, suas cenas e implementar a lógica do jogo.
  • Teste no Unity. Exporte para uma plataforma.
  • Teste nessa plataforma. Implantar.

Mas espere, eu quero mais!

Este artigo serve como uma visão geral da arquitetura e do processo no Unity. Eu abordei a interface, os fundamentos da atribuição de código, GameObjects, componentes, Mono, .NET e muito mais. Isto está preparado para o próximo artigo onde eu irei falar mais sobre como montar componentes do jogo para um jogo 2D. Fique de olho no Microsoft Virtual Academy, pois irei fazer um evento de aprendizagem de dois dias sobre o Unity no final do verão. Veja os eventos de aprendizagem regionais em unity3d.com/pages/windows/events.


Adam Tuliper é um evangelista técnico sênior da Microsoft na ensolarada California. Ele é um desenvolvedor de jogos indie, co-administrador do Orange County Unity Meetup e autor do pluralsight.com. Ele e sua mulher estão prestes a ter seu terceiro filho, portanto, entre em contato como ele enquanto ele ainda tem tempo livre em adamt@microsoft.com ou no Twitter em twitter.com/AdamTuliper.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo: Matt Newman (Subscience Studios), Jaime Rodriguez (Microsoft) e Tautvydas Žilys (Unity)