A implementação de padrões comuns de design de programação de jogos em seu projeto Unity pode ajudá-lo a criar e manter com eficiência uma base de código limpa, organizada e legível. Os padrões de design reduzem o tempo de refatoração e teste, acelerando os processos de desenvolvimento e contribuindo para uma base sólida para o crescimento do jogo, da equipe e dos negócios.
Pense nos padrões de projeto não como soluções prontas que você pode copiar e colar no seu código, mas como ferramentas extras que podem ajudá-lo a criar aplicativos maiores e escalonáveis.
Esta página explica os padrões de design Model View Controller (MVC) e Model View Presenter (MVP).
O conteúdo aqui é baseado no livro eletrônico gratuito, Eleve o nível de seu código com padrões de programação de jogos.
Confira mais artigos da série de padrões de design de programação de jogos do Unity no hub de práticas recomendadas do Unity ou por meio destes links:
Você pode usar os padrões de projeto Model View Controller (MVC) e Model View Presenter (MVP) para separar os dados e a lógica do seu aplicativo da forma como eles são apresentados. Esses padrões aplicam os princípios de "separação de preocupações", que podem melhorar a flexibilidade e a capacidade de manutenção de sua base de código.
No desenvolvimento de jogos em Unity, você pode usar esses padrões para separar a lógica de um jogo em componentes distintos, como os dados (Modelo), a representação visual (Exibição) e a lógica que controla a interação entre os dois (Controlador ou Apresentador).
O MVC é uma família de padrões de projeto comumente usados no desenvolvimento de interfaces de usuário em aplicativos de software.
A ideia geral por trás do MVC é separar a parte lógica do software dos dados e da apresentação. Isso ajuda a reduzir as dependências desnecessárias e, possivelmente, o código espaguete.
Como o nome indica, o padrão MVC divide seu aplicativo em três camadas:
O modelo armazena dados: O modelo é estritamente um contêiner de dados que contém valores. Ele não executa lógica de jogo nem executa cálculos.
A visualização é a interface: O View formata e renderiza uma apresentação gráfica dos seus dados na tela.
O Controlador lida com a lógica: Pense nisso como o cérebro. Ele processa os dados do jogo e calcula como os valores mudam no tempo de execução.
Essa separação de preocupações também define especificamente como essas três partes interagem entre si. O Modelo gerencia os dados do aplicativo, enquanto a Visualização exibe esses dados para o usuário. O Controlador processa a entrada e executa todas as decisões ou cálculos nos dados do jogo. Em seguida, ele envia os resultados de volta para o Modelo.
O Controlador não contém nenhum dado de jogo em si. Nem o View. O design MVC limita o que cada camada faz. Uma parte mantém os dados, outra parte processa os dados e a última exibe esses dados para o usuário.
Superficialmente, você pode pensar nisso como uma extensão do princípio da responsabilidade única. Cada parte faz uma coisa e a faz bem, o que é a principal vantagem da arquitetura MVC.
Ao desenvolver um projeto Unity com MVC, a estrutura de IU existente (o kit de ferramentas de I U ou a IU do Unity) funciona naturalmente como a visualização. Como o mecanismo fornece uma implementação completa da interface do usuário, não será necessário desenvolver componentes individuais da interface do usuário do zero.
No entanto, seguir o padrão MVC tradicional exigiria que o código específico da visualização ouvisse quaisquer alterações nos dados do modelo em tempo de execução.
Embora essa seja uma abordagem válida, muitos desenvolvedores do Unity optam por usar uma variação do MVC em que o Controlador atua como um intermediário. Aqui, a visualização não observa diretamente o modelo. Em vez disso, ele faz algo parecido com o diagrama acima.
Essa variação do MVC é chamada de design Model View Presenter, ou MVP. O MVP ainda preserva a separação de preocupações com três camadas de aplicativos distintas. No entanto, ele altera ligeiramente as responsabilidades de cada parte.
No MVP, o Presenter (chamado de Controller no MVC) atua como um intermediário para as outras camadas. Ele recupera dados do modelo e os formata para exibição na visualização. O MVP alterna qual camada manipula a entrada. Em vez do controlador, a visualização é responsável por lidar com a entrada do usuário.
Observe como os eventos e o padrão do observador fazem parte desse design. O usuário pode interagir com os componentes Button, Toggle e Slider da Unity UI. A camada View envia essa entrada de volta ao Presenter por meio de eventos da interface do usuário, e o Presenter, por sua vez, manipula o Model. Um evento de mudança de estado do modelo informa ao apresentador que os dados foram atualizados. O Presenter passa os dados modificados para o View, que atualiza a interface do usuário.
Um projeto de amostra está disponível no Github, que demonstra diferentes padrões de design de programação, incluindo um exemplo de como implementar uma variação do MVP.
O exemplo do MVP consiste em um sistema simples que mostra a saúde de um personagem ou item. Este exemplo tem tudo em uma classe que mistura os dados e a interface do usuário, mas isso não seria bem dimensionado em produções do mundo real. Adicionar mais funcionalidades se tornaria mais complicado à medida que você precisasse expandi-las. Além disso, o teste e a refatoração resultariam em muita sobrecarga.
Em vez disso, você pode reescrever seus componentes de saúde de uma forma mais centrada no MVP, começando por dividir seus scripts em Health e HealthPresenter.
No projeto de amostra, você pode clicar para danificar o objeto-alvo representado por um disco de tiro(ClickDamage.cs) ou redefinir a saúde com o botão. Esses eventos informam o HealthPresenter (que invoca Damage ou Reset) em vez de alterar o Health diretamente. O texto da interface do usuário e o controle deslizante da interface do usuário são atualizados quando o Health gera um evento e notifica o HealthPresenter de que seus valores foram alterados.
Vamos nos aprofundar no que poderia ser um componente de saúde. Nessa versão, o Health serve como modelo. Ele armazena o valor real da integridade e invoca um evento, HealthChanged, toda vez que esse valor é alterado. O Health não contém lógica de jogo, apenas métodos para incrementar e decrementar os dados.
Isso permite uma distinção clara entre os dados, a forma como são apresentados e a forma como são controlados.
O MVP (e o MVC) realmente se destaca em aplicativos de software maiores e com muita interface do usuário, mas não se limita a esses casos de uso. Se o seu jogo requer uma equipe considerável para ser desenvolvido e você espera mantê-lo por um longo período após o lançamento, poderá ver os seguintes benefícios:
Divisão suave do trabalho: Como você separou a visualização do apresentador, o desenvolvimento e a atualização da interface do usuário podem ocorrer de forma quase independente do restante da base de código, o que permite dividir o trabalho entre desenvolvedores especializados. Você tem desenvolvedores front-end especializados na sua equipe? Deixe que eles cuidem da visualização.
Teste de unidade simplificado com MVP e MVC: Esses padrões de design separam a lógica do jogo da interface do usuário. Dessa forma, você pode simular objetos para trabalhar com seu código sem precisar entrar no modo Play no Editor. Isso pode economizar uma quantidade considerável de tempo.
Código legível que pode ser mantido: Você tenderá a criar classes menores com esse padrão de design, o que facilita a leitura. Menos dependências geralmente significam menos lugares para o software quebrar, menos lugares que podem estar escondendo bugs e testes mais fáceis.
Embora o MVC e o MVP sejam amplamente difundidos no desenvolvimento da Web ou de software empresarial, muitas vezes os benefícios não serão aparentes até que o aplicativo atinja um tamanho e uma complexidade suficientes. Você precisará considerar o seguinte antes de implementar qualquer um dos padrões em seu projeto Unity:
É preciso planejar com antecedência: MVC e MVP são padrões arquitetônicos maiores. Para usar um deles, você precisará dividir suas turmas por responsabilidade, o que requer alguma organização e mais trabalho inicial. Os padrões de design são mais bem utilizados de forma consistente, portanto, você deve estabelecer uma prática para organizar a interface do usuário e garantir que a sua equipe esteja a par.
Nem tudo em seu projeto Unity se encaixará no padrão: Em uma implementação MVC ou MVP "pura", tudo o que é renderizado na tela realmente faz parte da visualização. Nem todo componente Unity é facilmente dividido entre dados, lógica e interface (por exemplo, um MeshRenderer). Além disso, scripts simples podem não trazer muitos benefícios do MVC/MVP.
Você precisará avaliar onde pode se beneficiar mais do padrão. Normalmente, você pode deixar que os testes unitários o orientem. Se o MVC/MVP puder facilitar os testes, considere-os para esse aspecto do aplicativo. Caso contrário, não tente forçar o padrão em seu projeto.
Você encontrará muitas outras dicas sobre como usar padrões de design em seus aplicativos Unity, bem como os princípios SOLID, no e-book gratuito Eleve o nível de seu código com padrões de programação de jogos.
Se você quiser obter instruções mais detalhadas sobre o uso da interface do usuário do Unity e do kit de ferramentas da interface do usuário, consulte o guia completo, Design e implementação da interface do usuário no Unity escrito por profissionais de UI.
Você pode encontrar todos os e-books e artigos técnicos avançados do Unity no hub de práticas recomendadas. Os e-books também estão disponíveis na página de práticas recomendadas avançadas na documentação.