O que são e como usar Assembly Definitions na Unity

Por padrão, a Unity compila a maioria dos scripts para o mesmo assembly. Isso significa que toda vez que um script é modificado todo o projeto deve ser compilado, incluindo assets e plugins de terceiros, como aqueles adquiridos através da Asset Store, por exemplo. Isso faz com que conforme o projeto cresça o tempo de compilação fique cada vez mais demorado. 

Porém podemos criar Assembly Definitions para dividir o projeto em partes menores. Uma das vantagens de criar Assembly Definitions na Unity é poder melhorar o tempo de compilação do projeto. 

Porém as vantagens vão além disso, com Assembly Definitions fica mais fácil organizar nosso código em módulos lógicos independentes um do outro, facilitando a reutilização de código entre projetos. Além disso, podemos criar Assembly Definitions que serão compilados e incluídos nas builds apenas para certas plataformas. Por último, caso você esteja pensando em criar testes de unidades para seu projeto com o pacote Unity Test Framework, Assembly Definitions é um requisito.

O que são assemblies?

Antes de aprendermos a criar Assembly Definitions na Unity, vamos entender o que são Assembly Definitions já que ele não é conceito ligado apenas a engine e sim a linguagem de programação C#.

As assemblies são a unidade mais básica dos programas criados usando a plataforma .NET. Na prática elas são uma coleção de arquivos de código fonte, imagens e outros, que são compilados juntos formando a funcionalidade do programa. São das assemblies que são criados os arquivos .exe e .dll.

Essa divisão permite que programas grandes sejam divididos em partes lógicas independentes. Isso facilita o compartilhamento de código fonte entre diferentes programas, o controle de versões, a segurança e modificações sem que outras partes do sistema sofram muitos impactos. 

Como usar Assembly Definition na Unity?

Por padrão um projeto na Unity é compilado para dois assembly. Um assembly será usado para compilar todos os arquivos do projeto que serão usados na versão final do jogo. Já o outro, será usado para todos arquivos colocados em uma pasta chamada “Editor”, esse assembly será compilado apenas no editor.

Porém a Unity nos permite criar quantos assemblies quisermos através de um asset chamado Assemble Definition e o melhor é que esse processo é super simples.

Como criar Assembly Definition

Para criar um Assembly Definition basta clicar com o botão direito sobre a pasta em que você gostaria de criar o arquivo e no menu que se abriu selecionar Create > Assembly Definition. Dê um nome ao arquivo.

Com isso, a Unity irá compilar o projeto.

Ao criar um Assembly Definition a Unity irá incluir no novo assembly todos arquivos que estiverem na pasta ou em subpastas em que esse Assembly Definition foi criado.

Por padrão a propriedade Name do Assembly Definition é preenchida com o mesmo nome do arquivo, porém podemos modificar esse valor se quisermos. Para isso, selecione o arquivo e na janela Inspector altere o valor da propriedade Name. Porém, fique atento já que esse nome é importante porque é através dele que o .NET identifica o assembly e deve ser único no projeto.

Você também pode definir um namespace padrão aqui. Esse namespace será adicionado a todo script novo que for criado pela engine na pasta ou em subpastas desse Assembly Definition.

Além dessas existem diversas opções que podemos configurar, porém não irei entrar em detalhes em todas elas e irei explicar aquelas que julgo mais importantes para a maioria dos projetos. Caso você queira que explique melhor alguma opção deixe seu comentário, você pode também encontrar mais opções no manual da Unity sobre Assembly Definition.

Referências a outros assemblies

Um problema que pode acontecer ao criar um Assembly Definition em um projeto que já está em desenvolvimento, é que provavelmente iremos ver uma série de erros no console. Isso acontece porque, como falei, ao criar o Assembly Definition isolamos esse código do resto dos códigos que estão no projeto.

Para resolver esse problema é bem simples, com o arquivo Assembly Definition selecionado, na janela Inspector, clique no sinal de mais na lista da propriedade Assembly Definition References. E no campo que apareceu, clique na bolinha para selecionar os assemblies necessários para que seu código funcione.

Em seguida clique no botão Apply para confirmar as alterações.

Adicionar novas referências apesar de ser um processo simples, pode ser trabalhoso saber quais Assembly Definition é preciso incluir para que o projeto funcione. E a melhor dica que posso dar é que você leia com atenção a mensagem de erro na janela Console, e na janela em que você escolhe qual assembly você quer referenciar vá eliminando as opções que não fazem sentido.

Como cada projeto é diferente, não é possível eu dizer quais referências você precisa, mas para dar um exemplo do que eu disse acima. Nesse projeto, por exemplo, ao criar o Assembly Definition o console tem 33 erros. 

Vamos começar do início, a primeira mensagem de erro diz “The type or namespace name ‘TMPro’ could not be found”, ou seja, o namespace TMPro não pode ser encontrado. Eu sei que esse namespace pertence ao pacote TextMeshPro.

Com essa informação, procuro por esse nome na janela para selecionar o assembly e vejo quais opções aparecem. Aqui por exemplo, lendo os nomes temos podemos deduzir que queremos a primeira opção, já não quero nada que tenha a ver com o editor ou com teste. Selecione e confirme as alterações.

E olha só, de 32 erros, para apenas 5.

Agora a primeira mensagem de erro diz que o namespace InputSystem não existe.

Novamente procuro por esse pacote na lista de assemblies disponíveis e selecionar aquele que me parece fazer mais sentido para o meu projeto.

Nem sempre será fácil assim, mas é um bom ponto de partida. Caso tenha alguma dificuldade deixe seu comentário abaixo e irei tentar te ajudar.

Criando Assembly Definition para plataformas específicas

Com Assembly Definition podemos também definir para quais plataformas o assembly deve ser compilado.

Na propriedade Platforms encontramos uma lista com todas as plataformas que a Unity suporta. E ao marcar e desmarcar a opção Any Platform podemos escolher se queremos incluir ou excluir uma plataforma para qual esse assembly deve ser compilado.

Por exemplo, digamos que o código que criamos funciona em todas as plataformas menos no WebGL. Com a opção Any Platform marcada, podemos marcar a plataforma para que esse código não seja incluído quando fizermos o build do jogo para WebGL.

Digamos por exemplo, que uma determinada parte do nosso código só é relevante quando o jogo estiver no Android. Podemos desmarcar a opção Any Platform e na lista de plataforma marcar a opção para Android.

Criando Assembly Definition Reference

Digamos que criamos um Assembly Definition para o projeto, mas por algum motivo queremos que o código que vamos criar não esteja na mesma pasta ou em uma subpasta desse arquivo mas queremos que ele faça parte do mesmo assembly.

Para resolver esse problema podemos criar Assembly Definition Reference. 

Clique com o botão direito do mouse sobre a pasta que você quer criar o arquivo e no menu que aparecerá selecione Create > Assembly Definition Reference. Dê um nome ao arquivo.

Selecione o arquivo e clique na bolinha na propriedade Assembly Definition e na janela que abriu selecione o assembly que você gostaria que esse código fizesse parte, em seguida clique em Apply.

Assembly Definition Reference funcionam de forma similar a Assembly Definition, isto é todo o código que estiver na pasta em que o arquivo foi criado ou em subpastas serão incluídos no assembly que definimos no arquivo.

Pastas especiais

Na Unity alguns nomes de pastas têm significados especiais, um desses nomes é Editor. Usamos essa pasta quando queremos que os arquivos de scripts que criamos nela sejam executados apenas no editor. Podemos criar uma pasta com esse nome em qualquer lugar do nosso projeto e os scripts nela serão automaticamente adicionados ao assembly Assembly-CSharp-Editor.dll que é executado apenas no editor e não é incluído na build do jogo.

Porém ao criar um arquivo Assembly Definition essa pasta perde o significado especial e precisamos criar uma arquivo Assembly Definition na pasta que será compilado apenas para o editor. Também podemos usar Assembly Definition Reference como vimos na seção anterior.

Conclusão

Ao usar Assembly Definition na Unity podemos organizar nosso código melhor, dividindo ele em partes lógicas e manter ele separado do código de terceiros que podemos encontrar na Asset Store, por exemplo. 

Além disso, ao dividir o nosso código em partes menores, melhoramos o tempo de compilação quando fazemos modificações, já que apenas o que foi modificado e o que dependente desse assembly precisa ser recompilado. Sem contar que essa é uma etapa fundamental caso queiramos começar a criar testes automatizados para o nosso projeto.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *