Pesquisar em Unity

3 maneiras legais de construir seu jogo com Objetos Scriptáveis

Last updated: December 2018

O que você encontrará nesta página: instruções prontas para usar sobre como manter o código do seu jogo fácil de gerenciar, alterar e depurar ao arquitetar com Scriptable Objects.

Essas são as dicas de Ryan Hipple, engenheiro-chefe da Schell Games. Ele tem muita experiência usando Objetos Scriptáveis para arquitetar jogos. Você pode assistir à palestra de Ryan na Unite sobre Scriptable Objects aqui. Também recomendamos que você veja a sessão do engenheiro Unity Richard Fine para uma ótima introdução aos Objetos Scriptáveis. Obrigado, Ryan!

Em suma, o que são Objetos Scriptáveis?

ScriptableObject é uma classe Unity serializável que permite armazenar grandes quantidades de dados compartilhados independentemente das instâncias de script. O uso de Objetos Scriptáveis facilita o gerenciamento de alterações e a depuração. Você pode criar um nível de comunicação flexível entre os diferentes sistemas do jogo, de modo que, em geral, é mais fácil alterar e adaptar as coisas à medida que você avança, bem como reutilizar os componentes.

Três pilares da engenharia de jogos inteligentes

Mantenha as coisas modulares ...

  • Evite criar sistemas que dependam diretamente uns dos outros. Por exemplo, um sistema de inventário deve ser capaz de se comunicar com os outros sistemas em seu jogo, mas você não deve criar uma referência rígida entre eles, pois isso dificulta a reimplementação de sistemas em diferentes configurações e vínculos.
  • Crie cenas a começar de zero: evite ter dados temporários entre suas cenas. Para cada nova cena, deve haver uma pausa e uma carga limpa. Isso permite que você tenha cenas com um comportamento exclusivo que não esteja presente em outras cenas, sem precisar fazer um corte.
  • Configure Prefabs para que elas trabalhem sozinhas. Tanto quanto possível, qualquer prefab que você colocar em uma cena deve ter essa funcionalidade. Isso é extremamente útil para equipes maiores em termos de controle de fonte, onde as cenas são uma lista de prefabs e as prefabs contêm a funcionalidade individual. Dessa forma, a maioria dos seus check-ins está no nível Prefabs, o que resulta em menos conflitos na cena.
  • Foque cada componente na resolução de um único problema. Isso simplifica a montagem de vários componentes para criar algo novo.

... Editáveis

  • Faça o máximo possível do seu jogo orientado a dados: se você criou seus sistemas de jogo como máquinas que processam dados como instruções, você poderá fazer alterações no jogo, mesmo quando estiver em execução, de forma mais eficiente.
  • Se seus sistemas forem configurados para serem o mais modulares e baseados em componentes possível, será mais fácil editá-los, inclusive para seus artistas e designers. Se os designers puderem colocar as coisas no jogo sem ter que pedir uma função específica - em grande parte graças à implementação de pequenos componentes que executam uma função de cada vez - eles têm a capacidade de combinar esses componentes de maneiras diferentes para encontrar novas jogabilidades /mecânicas. Ryan diz que alguns dos recursos mais legais em que sua equipe trabalhou em seus jogos resultaram desse processo, que ele chama de "design emergente".
  • É fundamental que sua equipe possa fazer alterações no jogo em tempo de execução. Quanto mais alterações você fizer no tempo de execução, mais cedo encontrará o equilíbrio e os valores e, se puder restaurar seu status de tempo de execução, como é possível com Objetos Scriptáveis, você está em uma boa posição.

... E, depuráveis

Este é mais um subpilar dos dois primeiros. Quanto mais modular for o seu jogo, mais fácil será testar seções individuais. Quanto mais editável for o seu jogo, ou seja, quanto mais recursos ele tiver em sua própria visualização do Inspetor, mais fácil será depurá-lo. Certifique-se de poder visualizar o estado de depuração no Inspetor e nunca considere um recurso como concluído até ter um plano sobre como depurá-lo.

As três melhores dicas de Ryan para criar Objetos Scriptáveis

Variáveis

Uma das coisas mais simples que você pode fazer com um objeto Scriptável é uma variável autônoma baseada em recursos. Aqui está um exemplo de FloatVariable, mas a explicação também se aplica a qualquer outro tipo de variável serializável.

Variável de flutuação para scriptable object Unity

Isso permite que qualquer membro de sua equipe, independentemente de seu conhecimento técnico, defina uma nova variável de jogo criando um novo recurso FloatVariable. Qualquer MonoBehaviour ou ScriptableObject pode usar um FloatVariable público em vez de um Public Float para referenciar esse novo valor compartilhado.

Ainda melhor: se um MonoBehaviour muda o Value de um FloatVariable, outros MonoBehaviours podem ver essa alteração. Isso cria um tipo de camada de mensagens entre sistemas que não precisam de referências entre si.

Um exemplo de aplicação disso é o HP de um jogador. Em um jogo com um único jogador local, o HP do jogador pode ser uma FloatVariable chamada PlayerHP.Se o jogador sofrer dano, o PlayerHP diminuirá. Se o jogador se recuperar, "PlayerHP" aumenta.

Agora imagine uma barra de saúde prefab na cena. A barra de saúde monitora a variável PlayerHP para atualizar sua exibição. Sem quaisquer alterações de código, poderia facilmente apontar para algo diferente, como uma variável PlayerMP. A barra de saúde não sabe nada sobre o jogador na cena, apenas lê a mesma variável que o jogador escreve.

Conduzindo a morte de jogador com um scriptable object Unity

Assim que estivermos configurados dessa forma, será fácil adicionar mais elementos para ver o PlayerHP. O sistema de música pode ser alterado à medida que o PlayerHP fica baixo, inimigos podem mudar seus padrões de ataque quando sabem que o jogador está fraco, efeitos de espaço de tela podem enfatizar o perigo do próximo ataque. Nesse ponto, o importante é que o script do Jogador não envie mensagens a esses sistemas e que esses sistemas não precisem saber sobre o game object do jogador. Você também pode ir ao inspector enquanto executa o jogo e alterar o valor do PlayerHP para fazer testes.

Ao editar o valor de uma FloatVariable, pode ser uma boa ideia copiar seus dados em um valor de tempo de execução para não alterar o valor armazenado no disco para o ScriptableObject. Se você fizer isso, o MonoBehaviours deve acessar o RuntimeValue para evitar a edição do InitialValue salvo no disco.

Variável de flutuação para scriptable object Unity

Eventos

Um dos meus recursos favoritos que podem ser criados além dos Objetos Scriptáveis é um sistema de eventos. As arquiteturas de eventos ajudam a modularizar seu código enviando mensagens entre sistemas que não estão diretamente conectados. Eles permitem reações a mudanças de estado sem monitorar constantemente em um loop de atualização.

Este sistema de eventos consiste em duas partes: um GameEvent ScriptableObject e um GameEventListener MonoBehaviour. Designers podem criar qualquer número de GameEvents no projeto para representar mensagens importantes que podem ser enviadas. Um GameEventListener espera que um GameEvent específico seja gerado e responde invocando um UnityEvent (que não é um evento verdadeiro, mas uma chamada de função serializada).

Event listener para scriptable object Unity

Event listener para scriptable object Unity

Event listener para scriptable object Unity

Um exemplo disso é lidar com a morte do jogador em um jogo. Este é um ponto em que grande parte da execução pode mudar, mas pode ser difícil determinar onde codificar toda a lógica. Deve o script do jogador acionar a IU do Game Over, uma mudança de música? Devem os inimigos em cada frame verificar se o jogador ainda está vivo? Um sistema de eventos nos ajuda a evitar essas dependências problemáticas.

Quando o jogador morre, o script do jogador chama Raise no evento OnPlayerDied. O script do jogador não precisa saber qual sistema está cuidando dele, apenas transmite. A IU do Game Over ouve o evento OnPlayerDied e inicia a animação, um script de câmera pode ouvi-lo e começar a desvanecer para preto, e um sistema de música pode responder com uma mudança na música. Podemos deixar qualquer inimigo ouvir no OnPlayerDied e acionar uma animação ou mudança de estado para o comportamento inativo.

Esse padrão torna incrivelmente fácil adicionar novas reações à morte de um jogador. Também é fácil testar essas reações chamando Raise no evento por meio de um código de teste ou botão no Inspetor.

Conduzindo a morte de jogador com um scriptable object Unity

O sistema de eventos que criei na Schell Games se tornou algo mais complicado e inclui recursos que permitem a transmissão de dados e tipos de geração automática. Não posso explicar todos os detalhes aqui, mas este exemplo foi essencialmente o ponto de partida do que usamos hoje.

Sistemas

Os Objetos Scriptáveis não precisam ser apenas dados. Pegue qualquer sistema que você implementar em um MonoBehaviour e veja se você pode mover a implementação para um ScriptableObject. Em vez de ter um InventoryManager em um MonoBehaviour DontDestroyOnLoad, tente colocá-lo em um ScriptableObject.

Por não estar ligado à cena, ele não tem um Transform e não recebe as funções de Atualização, mas manterá o estado entre carregamentos de cenas sem qualquer inicialização especial. Em vez de um singleton, use uma referência pública para o objeto do seu sistema de inventário quando precisar de um script para acessar o inventário. Isso torna a troca em um teste ou tutorial de inventário mais fácil do que se estivesse usando um singleton.

Imagine um script de jogador vinculado ao sistema de inventário. Quando o jogador avança, o script interroga o inventário para conhecer os objetos possuídos e encaminhar os equipamentos. A IU da equipe também pode ser vinculada ao inventário e revisar os objetos para determinar quais selecionar.

Mais recursos

Queremos saber! Você gostou deste conteúdo?

Sim, continue. Bem. Poderia ser melhor

Unity Buffbot está aqui para facilitar seu trabalho

Cadastre-se para receber know-how técnico e criativo semanal de especialistas da Unity.

Subscribe
Eu entendi

Usamos cookies para garantir a melhor experiência no nosso site. Clique aqui para obter mais informações.