Iteração rápida de design em Breachers usando AssetPostprocessor e Blender

JEL SADONES / UNITY TECHNOLOGIESLead Level Design/Tech Art, Triangle Factory
Apr 18, 2023|17 Min
Iteração rápida de design em Breachers usando AssetPostprocessor e Blender
Esta página da Web foi automaticamente traduzida para sua conveniência. Não podemos garantir a precisão ou a confiabilidade do conteúdo traduzido. Se tiver dúvidas sobre a precisão do conteúdo traduzido, consulte a versão oficial em inglês da página da Web.
A Triangle Factory é uma empresa de jogos belga de rápido crescimento que usa o Unity para criar títulos VR multijogador de alta qualidade, como Hyper Dash e seu último jogo, Infratores. A Triangle Factory utiliza ferramentas como Cinemachine, Unity Profiler, Game Server Hosting, Matchmaker, Voice Chat (Vivox)e Friends para criar uma experiência imersiva para os jogadores.



Neste blog, Jel Sadones, líder de design de níveis/arte técnica, e o desenvolvedor líder Pieter Vantorre nos mostram seu pipeline do Blender para o Unity e como eles deram vida ao seu título FPS tático de VR , Breachers .

O Unity tem sido nosso mecanismo e ambiente de desenvolvimento preferidos por mais de uma década, e passamos por muitos fluxos de trabalho ao longo dos anos para modelagem e design de ambientes. Isso inclui o uso de ferramentas de modelagem no mecanismo, como o ProBuilder (que ainda usamos e adoramos para prototipagem rápida) e a montagem de cenas de Prefabs criados em outros pacotes de modelagem. Para nossos projetos atuais, porém, chegamos a um fluxo de trabalho em que modelamos e organizamos nossos níveis no Blender e contamos com o AssetPostprocessor da Unity para integrá-los ao nosso projeto Unity .

Neste artigo, compartilharemos com você como chegamos a esse fluxo de trabalho e como ele oferece suporte ao tipo de iteração de design rápida que precisamos para nossos jogos.

Encontrando o fluxo de trabalho certo

Em 2021, lançamos nosso primeiro grande título de VR , Hyper Dash, um jogo de tiro em arena 5v5 de ritmo acelerado. Quando começamos o desenvolvimento do jogo em 2019, tínhamos um fluxo de trabalho básico do Blender para o Unity que provavelmente parece familiar para muitos: Nós simplesmente modelamos a geometria no Blender, exportamos nossos ativos como arquivos FBX e os integramos manualmente no Unity. A integração manual envolveu várias etapas:

  • Configurando objetos dinâmicos na cena, como coleta de armas, portas de spawn, pontos de captura
  • Colocar colisores para evitar que os jogadores andem ou se teletransportem em certas áreas
  • Configurando guias invisíveis para permitir que os bots se comportem corretamente
  • Etc.
Hyper Dash (2021)

Esse processo pode funcionar bem para projetos menores, mas rapidamente se torna complicado à medida que o projeto cresce e evolui. Quando começamos a planejar o desenvolvimento do nosso próximo título, sabíamos que precisaríamos de um fluxo de trabalho drasticamente melhorado.

Usando o protótipo para identificar pontos problemáticos

Breachers é um jogo de tiro competitivo com layouts de níveis complexos, mecânicas de jogo mais sutis, sistemas mais técnicos em jogo e um nível mais alto de polimento gráfico voltado para a mais nova geração de hardware VR autônomo. Em termos de complexidade, ele vai vários passos além do Hyper Dash, e rapidamente sentimos os efeitos disso em nosso fluxo de trabalho.

Infratores: Rapel de arranha-céu em 4K

Na fase de prototipagem, ainda dependemos muito de Prefabs para objetos dinâmicos, como barricadas de janelas, por exemplo. Esses são objetos que colocamos dentro das janelas para bloquear a linha de visão entre o interior e o exterior, evitando que os times se vejam durante a fase de aquecimento do jogo.

Ao testar nosso protótipo, estávamos constantemente movendo as janelas para melhorar a jogabilidade, o que significava alterar a geometria no Blender e reexportar para o Unity e, então, mover manualmente os objetos da barricada para corresponder às nossas alterações. Muitas horas foram gastas voando pela visualização de cena do Unity, verificando e corrigindo manualmente esse tipo de coisa. Ainda assim, tivemos mais de um teste de jogo em que só percebemos durante o jogo que algo havia sido esquecido.

Figura 2: Imagem de Breachers fornecida pela Triangle Factory (Prototipagem do nível Hideout)
Figura 3.5: Imagem de Breachers fornecida pela Triangle Factory (A versão final de Hideout)

Obviamente, esse fluxo de trabalho não nos daria a capacidade de iterar rapidamente nossos designs de mapas enquanto fazíamos testes, tanto internamente quanto como parte do nosso alfa aberto, onde planejamos disponibilizar um mapa gratuitamente para obter feedback da comunidade. Estávamos ansiosos por todo esse feedback, mas não pelo esforço manual envolvido na aplicação dele aos nossos mapas.

Outra possível desvantagem de um fluxo de trabalho de design baseado em pré-fabricados é o desempenho. Nosso principal objetivo é usar headsets VR independentes e móveis para nossos jogos. Queremos levar os recursos visuais o mais longe possível, então precisamos extrair até a última gota de desempenho do nosso fluxo de trabalho.

Montar níveis a partir de Prefabs pode ser menos eficiente do que criar uma malha estanque em um programa de modelagem. Se você encaixar duas peças de parede modulares, sempre terá um loop geométrico não mesclado entre elas. Com os Prefabs, também é fácil acabar colocando muita geometria na sua cena que não é visível (porque está na parte inferior de um objeto ou encostada em uma parede), mas ainda ocupa um espaço valioso no mapa de luz. Em um nível inteiro, essas pequenas ineficiências podem resultar em desempenho desperdiçado e visuais reduzidos.

Figura 3: Imagem de Breachers fornecida pela Triangle Factory (janelas quebráveis em um nível de sandbox durante o protótipo)

O último problema com Prefabs que queremos mencionar é que pode ser fácil quebrar coisas ao aplicar alterações aparentemente inocentes ao modelo de origem no Blender, como renomear um objeto. À medida que um jogo ou nível evolui, muitas vezes você deseja reorganizar seus recursos e dar a eles nomes melhores ou mais consistentes. Mas renomear um objeto no Blender e reexportá-lo pode facilmente (e sem aviso) quebrar as substituições e adições feitas ao objeto no Unity, levando a regressões.

Neste exemplo simplificado, temos uma grelha de ventilação pré-fabricada e queremos que saia fumaça por ela. Depois de importar a malha para o Unity, nosso artista adicionou o sistema de partículas de fumaça como um objeto filho e adicionou um componente de tipo de superfície ao Prefab para marcá-lo como um objeto de metal.

Aqui você pode ver o que acontece se renomearmos nossa malha no Blender:

Ao reimportar a malha com o nome atualizado, o Unity não consegue mais encontrar a malha antiga pelo nome, então ele remove o objeto do modelo Prefab. Os filhos desse objeto removido são movidos para a raiz do Prefab e os scripts existentes são removidos, novamente levando ao trabalho de limpeza manual que preferiríamos evitar.

Definir metas claras para o pipeline de produção

À medida que a fase de prototipagem de Breachers terminava e nos preparávamos para entrar em modo de produção total no início de 2022, nossas equipes de arte e desenvolvimento se reuniram e investigaram o que poderíamos fazer para resolver esses problemas. Definimos metas claras para nosso pipeline de ativos ideal, um que daria suporte à iteração rápida e flexível necessária para Breachers:

  • Toda a criação e modificação da geometria dos níveis deve acontecer no Blender.
  • WYSIWYG: O que um designer cria no Blender deve corresponder o máximo possível ao resultado no Unity .
  • Quando algo é atualizado no Blender, a importação das alterações para o Unity deve acontecer automaticamente e não exigir nenhum esforço manual.
Figura 4: Imagem de Breachers fornecida pela Triangle Factory
Fazendo o Blender amar o Unity

Como mencionado acima, nosso principal objetivo era ter uma visualização precisa do jogo no Blender – não apenas refletindo adequadamente como o resultado final ficará no Unity , mas também como a mecânica do jogo é configurada. A jogabilidade em Breachers não depende apenas do layout do nível, mas também de objetos dinâmicos (como paredes quebráveis) e elementos invisíveis (como volumes de som e aceleradores). Queremos que todas essas informações sejam visíveis na fase de design e transferidas precisamente para o Unity.

Figura 5: Imagem de Breachers fornecida pela Triangle Factory [Parte do nosso nível Skyscraper no Blender (somente geometria de nível estático e adereços)]
Figura 6: Imagem de Breachers fornecida pela Triangle Factory (a mesma cena com objetos dinâmicos adicionados)
Figura 7: Imagem de Breachers fornecida pela Triangle Factory (a mesma cena importada para o Unity, antes do cozimento leve)
Figura 8: Imagem de Breachers fornecida pela Triangle Factory (A cena final em Unity)
Propriedades personalizadas e AssetPostprocessor da Unity

Propriedades personalizadas são essenciais para nosso fluxo de trabalho e as atribuímos a objetos no Blender. Eles são então transportados para o Unity pelo formato FBX, para que possamos lê-los e executar lógica personalizada quando nossos ativos são importados para o Unity.

Figura 9: Imagem de Breachers fornecida pela Triangle Factory (Um exemplo de propriedades personalizadas atribuídas a um objeto no Blender)

Isso nos dá uma grande flexibilidade e estabilidade. Essas propriedades permanecem conectadas aos objetos por todo o pipeline, para que possamos reorganizar e renomear coisas em nossos níveis o quanto quisermos, sem nos preocupar com coisas quebrando ou ficando fora de sincronia.

O Unity tem uma classe poderosa chamada AssetPostprocessor, que permite modificações de ativos enquanto eles estão sendo importados. É isso que usamos no momento da importação para analisar essas propriedades personalizadas e agir sobre elas.

Casos de uso

Links pré-fabricados

Temos uma propriedade personalizada chamada PrefabLink, que informa ao Unity que o objeto importado do Blender deve ser substituído por um Prefab já existente no projeto do Unity , preservando a transformação do modelo importado. Isso nos permite colocar esses objetos dinâmicos no Blender , mantendo as vantagens dos Prefabs quando eles são importados para o Unity. As barricadas de janela na cena do Blender acima são um bom exemplo disso.

Figura 10: Imagem de Breachers fornecida pela Triangle Factory

Tipos de superfície

A definição de superfície é extremamente importante em Breachers. Andar em uma escada de metal soa diferente de andar em um piso de concreto. A penetração de uma bala na madeira é muito diferente da penetração no aço. E cada tipo de superfície tem seus próprios efeitos de impacto. Analisar cada suporte no Unity e marcá-lo como o tipo de superfície correto levaria muito tempo, então também abordamos isso na fase de design no Blender , definindo propriedades personalizadas em nossos aceleradores de geometria.

Bandeiras estáticas

Outra configuração importante para otimização são os sinalizadores estáticos do Unity. Definir essas configurações corretamente pode ter um impacto profundo em coisas como redução de visibilidade, cozimento leve e dosagem. Usando propriedades personalizadas no Blender, podemos defini-las em qualquer parte do nível, incluindo acessórios reutilizáveis, e fazer com que essas informações sejam transferidas para o Unity em todos os nossos níveis.

Colisores

Por fim, gostaríamos de compartilhar como configuramos os aceleradores. O Unity tem um sistema simples, mas eficaz, que detecta automaticamente variantes de nível de detalhe para modelos quando você adiciona um nome de ativo de modelo com _LOD0, _LOD1, etc. Ficamos inspirados por isso e criamos um sistema semelhante para aceleradores: Ao simplesmente ter geometria com _BoxCollider ou _NoCollision no nome, substituímos as malhas do Blender por colisores no Unity.

Figura 11: Imagem de Breachers fornecida pela Triangle Factory (Observe os nomes _BoxCollider e _NoCollision no Blender)
Figura 12: Imagem de Breachers fornecida pela Triangle Factory (Objeto marcado como _BoxCollider é traduzido para um BoxCollider real no Unity)
Exemplo de código

Como exemplo concreto, aqui está um trecho do nosso LevelSetupPostprocessor que lê propriedades personalizadas e atribui os sinalizadores estáticos corretos em cada objeto importado:

Personalizando o Blender para funcionar melhor com o Unity

Para que tudo isso funcionasse bem, tivemos que trabalhar um pouco também no Blender .

As propriedades personalizadas ficam um pouco escondidas na interface do Blender e exigiriam que os artistas digitassem manualmente as propriedades personalizadas toda vez, o que não é uma ótima experiência para o usuário. Depender da entrada manual de texto também seria muito propenso a erros, anulando grande parte da vantagem de configurar as coisas no Blender em primeiro lugar. Mudar de um fluxo de trabalho baseado em Prefabs para o Blender também nos fez perder algumas das vantagens dos Prefabs, como ter uma boa biblioteca de objetos para navegar e escolher. Felizmente, o Blender, assim como o Unity, é muito flexível e facilmente extensível.

Biblioteca de ativos do Blender

A resposta para o problema de organização do Prefab veio no Blender 3.2 com Bibliotecas de Ativos. Este sistema funciona um pouco como o sistema Prefab no Unity: Ele permite que você crie ativos em um arquivo separado e depois os importe para sua cena do Blender , enquanto as alterações no arquivo de ativos são refletidas automaticamente na cena do Blender . Além disso, ele garante que quaisquer propriedades personalizadas ou colisores sejam aplicados corretamente a cada instância deste ativo no Blender.

Figura 13: Imagem de Breachers fornecida pela Triangle Factory (parte da nossa biblioteca de adereços no Blender)
Figura 14: Imagem Breachers fornecida pela Triangle Factory (Todos os tipos de objetos dinâmicos que usam a propriedade personalizada PrefabLink)
Complementos personalizados do Blender

Para o Blender, escrevemos um complemento interno para ajudar a configurar as propriedades personalizadas em uma interface de usuário mais clara. Isso simplifica a configuração de propriedades personalizadas, bastando selecionar os objetos relevantes do Blender e clicar em um botão, em vez de digitar cada propriedade manualmente.

O complemento Bundle Exporter é um complemento de código aberto que usamos para exportar todos os nossos arquivos FBX com um clique. Nós o modificamos para funcionar também com propriedades personalizadas e atualizamos a interface do usuário para ter exportações mais rápidas para nossas necessidades específicas.

Figura 15: Imagem de Breachers fornecida pela Triangle Factory
Conclusão

Configurar nosso fluxo de trabalho de design de níveis para Breachers exigiu um grande investimento de tempo inicialmente, mas acreditamos que foi a escolha certa para o projeto. E também foi bem divertido!

À medida que desenvolvemos o jogo desde os blocos iniciais até os testes alfa e os meses que antecederam o lançamento final, a iteração em nossos níveis foi rápida e tranquila. Conseguimos eliminar despesas gerais e trabalho burocrático para nossos designers e artistas, ao mesmo tempo em que transferimos a eles responsabilidades que antes precisariam de um desenvolvedor.

Ficamos impressionados com a capacidade de integração entre Unity e Blender , e acreditamos firmemente que essa integração foi essencial para tornar Breachers um jogo com o qual estamos felizes e orgulhosos de compartilhar com o mundo.

Obrigado pela leitura e aproveite o jogo!

Imagem estática em 4K do VR FPS Breachers da Triangle Factory

Breachers da Fábrica Triângulo já está disponível. Confira mais blogs de desenvolvedores do Made with Unity aqui.