Unidade: conhecendo objetos programáveis

imagem

Neste tutorial, você aprenderá como criar e usar objetos Scriptable no Unity. Os objetos com script podem ajudar a melhorar seu fluxo de trabalho, reduzir o espaço ocupado na memória e até permitir que você divida a arquitetura do código.

De acordo com a documentação do Unity , ScriptableObject é um código de classe que permite criar objetos Scriptable no jogo para armazenar grandes quantidades de dados compartilhados, independentes das instâncias de script.

Há muitos motivos para usar objetos que podem ser gravados no Unity. Eles podem reduzir a quantidade de memória usada para cada prefab adicional, porque o Objeto Scriptable segue essencialmente o padrão de design Flyweight .

Outra vantagem dos objetos graváveis, que será o tema principal deste tutorial, é o uso deles para a transferência conveniente de dados. Consideraremos essa propriedade como um exemplo da criação de uma loja de espadas, que exibirá os parâmetros, preços e descrições de várias espadas.

Nota: este tutorial supõe que você esteja familiarizado com o editor do Unity. Você deve entender como editar o código em um editor de código e ter conhecimentos básicos de C #. Se você precisar melhorar suas habilidades no Unity, confira outros tutoriais do Unity .

Começando a trabalhar


Vamos começar baixando os materiais que precisamos.

Descompacte o arquivo baixado em um local conveniente para você e abra o projeto Scriptable Object Tutorial-Starter no Unity.

Você deverá ver a seguinte pasta criada como parte da aquisição do projeto:


  • _Configuração : para o tutorial, essa pasta não é necessária.
  • Cenas : contém uma cena do comerciante de espadas que abordaremos ao longo do tutorial. Abra esta cena.
  • Scripts : até o momento, existe apenas um script, mas durante o tutorial criaremos novos.
  • Ícones de espadas : Contém imagens estáticas de espadas individuais.
  • Pré -fabricados de Espadas : Contém as pré-fabricadas de todas as espadas na cena do Mercador de Espadas.

Criando um objeto programável


Para começar, vá para a cena Sword Merchant . Deve ficar assim:


Preparando objeto gravável


É hora de criar o primeiro Objeto Scriptable!

Na pasta Scripts , crie um novo script chamado SwordData . Esta classe será usada como um contêiner para todos os dados da espada exibidos na loja do comerciante de espadas.

Dentro desta classe, comece herdando de ScriptableObject vez de MonoBehaviour :

 public class SwordData : ScriptableObject { } 

Essa ação informa ao Unity que ainda queremos usar os recursos e métodos do Unity, assim como o MonoBehaviour comum, mas não precisamos mais anexar esse script ao GameObject. Em vez disso, será processado como qualquer ativo regular, que pode ser criado da mesma maneira que a criação de uma pré-fabricada, cena ou material.

Preencha o script com campos serializados, que conterão todos os dados correspondentes às informações exibidas na interface do usuário do Sword Merchant.

 public class SwordData : ScriptableObject { [SerializeField] private string swordName; [SerializeField] private string description; [SerializeField] private Sprite icon; [SerializeField] private int goldCost; [SerializeField] private int attackDamage; } 

  • swordName : string , na qual o nome da espada será armazenado.
  • description : string , na qual a descrição da espada será armazenada.
  • icon : o sprite que conterá o ícone da espada.
  • goldCost : int para armazenar o valor da espada em ouro.
  • attackDamage : int para armazenar dano ao atacar com uma espada.

Nota: SerializeField

No Unity, o atributo SerializeField permite que você tenha variáveis ​​de script privadas disponíveis no Inspector. Isso permitirá que você defina valores no editor sem fornecer acesso à variável de outros scripts.

Cada espada exigirá sua própria implementação exclusiva do objeto de script SwordData . Porém, antes de podermos criar essas implementações, precisamos adicionar um Objeto Scriptable ao Menu de Ativos.

Adicione nosso objeto gravável ao menu de ativos adicionando o seguinte atributo à classe SwordData :

 [CreateAssetMenu(fileName = "New SwordData", menuName = "Sword Data", order = 51)] public class SwordData : ScriptableObject 

  • fileName : nome padrão ao criar ativo.
  • menuName : nome do ativo exibido no menu Asset.
  • ordem : posicionamento do ativo no menu ativo. A unidade divide os ativos em subgrupos com um fator de 50. Ou seja, um valor de 51 coloca o novo ativo no segundo grupo do menu de ativos.

Se tudo for feito corretamente, você poderá ir para Ativos >> Criar e ver o novo ativo Sword Data no menu. Ele deve estar localizado no segundo grupo no recurso Pasta:


Você também pode clicar com o botão direito do mouse na janela Projeto e também ver o novo ativo Sword Data:


Adicionando dados


Organizaremos o projeto criando uma pasta chamada Objetos graváveis na pasta Scripts e, dentro dessa pasta, outra pasta chamada Dados da espada .

Dentro da recém criada pasta Sword Data, crie nosso primeiro ativo Sword Data.

O novo recurso Sword Data ainda deve ter o nome padrão especificado anteriormente fileName . Selecione um ativo e duplique seis vezes ( Ctrl / Cmd + D ) para criar sete ativos de Sword Data, um para cada uma das espadas. Agora renomeie cada ativo de acordo com os prefabs:


Clique no primeiro ativo Sword Data na pasta Sword Data e veja a janela Inspector :


Aqui vemos um ativo no qual as informações sobre uma espada específica serão armazenadas. Preencha as informações para cada espada. Tente dar a eles uma descrição única, valor em ouro e dano durante um ataque. No campo Icon Sprite, use os sprites correspondentes localizados na pasta Sword Icons :


Parabéns! Você criou um objeto programável e configurou vários ativos com esse objeto programável.

Usando objeto gravável


Agora começaremos a obter dados desses objetos programáveis.

Primeiro, precisamos adicionar alguns métodos getter públicos para que outros scripts possam acessar campos privados dentro do objeto programável. Abra SwordData.cs e adicione o seguinte nos campos adicionados anteriormente:

  public string SwordName { get { return swordName; } } public string Description { get { return description; } } public Sprite Icon { get { return icon; } } public int GoldCost { get { return goldCost; } } public int AttackDamage { get { return attackDamage; } } 

Abra o Sword.cs e adicione o seguinte código:

  [SerializeField] private SwordData swordData; // 1 private void OnMouseDown() // 2 { Debug.Log(swordData.name); // 3 Debug.Log(swordData.Description); // 3 Debug.Log(swordData.Icon.name); // 3 Debug.Log(swordData.GoldCost); // 3 Debug.Log(swordData.AttackDamage); // 3 } 

Aqui está o que adicionamos com este código:

  1. O contêiner de dados para os dados desta espada.
  2. OnMouseDown é uma função MonoBehaviour interna chamada quando o usuário pressiona o botão esquerdo do mouse.
  3. Exemplos de como obter dados do nosso recurso Objeto de Script

Volte para o Unity e vá para a janela Hierarquia . Selecione o objeto do jogo 1_Longsword no prefab da espada. Adicione o ativo 1_Longsword Data apropriado à variável Sword Data do script Sword.cs na janela Inspetor:


Clique em Reproduzir ( Ctrl / Cmd + P ) no editor do Unity e, em seguida, clique na espada mais à esquerda:


O console deve exibir informações semelhantes aos dados transferidos do ativo Sword Data.

Objetos graváveis ​​facilitam a substituição desses dados. Tente inserir diferentes objetos de script da Sword Data no campo Sword Data da espada.

Objetos graváveis ​​de eventos


Então, criamos um Objeto Scriptável e você viu como pode acessar seus dados dentro do jogo. Mas ainda precisamos integrar o Sword Data à interface do usuário!

Você pode usar o padrão Singleton rápido e sujo para isso. No entanto, agora temos outras possibilidades ...

... ou seja, Objetos Scriptable! Vamos usá-los para criar um código limpo e bem dividido.

Nesta seção, você aprenderá como criar eventos de jogos usando a classe UnityEvent .

Eventos do Jogo e Ouvintes


Na pasta Scripts, crie dois scripts: GameEvent.cs e GameEventListener.cs . Eles dependem um do outro, portanto, para se livrar dos erros, é necessário criar os dois.

 using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "New Game Event", menuName = "Game Event", order = 52)] // 1 public class GameEvent : ScriptableObject // 2 { private List<GameEventListener> listeners = new List<GameEventListener>(); // 3 public void Raise() // 4 { for (int i = listeners.Count - 1; i >= 0; i--) // 5 { listeners[i].OnEventRaised(); // 6 } } public void RegisterListener(GameEventListener listener) // 7 { listeners.Add(listener); } public void UnregisterListener(GameEventListener listener) // 8 { listeners.Remove(listener); } } 

Aqui está o que o código acima faz:

  1. Adiciona um GameEvent como um ativo ao Menu de ativos.
  2. GameEvent é um Objeto Scriptable, portanto, ele deve herdar de ScriptableObject.
  3. Lista de GameEventListeners a serem inscritos no GameEvent.
  4. Método para chamar todos os assinantes do GameEvent.
  5. O último GameEventListener assinado será o primeiro a ser chamado (último a chegar, primeiro a sair).
  6. Ligue para cada UnityEvent GameEventListeners.
  7. Um método que permite que GameEventListeners se inscreva neste GameEvent.
  8. Um método que permite que GameEventListeners cancele a inscrição neste GameEvent.


 using UnityEngine; using UnityEngine.Events; // 1 public class GameEventListener : MonoBehaviour { [SerializeField] private GameEvent gameEvent; // 2 [SerializeField] private UnityEvent response; // 3 private void OnEnable() // 4 { gameEvent.RegisterListener(this); } private void OnDisable() // 5 { gameEvent.UnregisterListener(this); } public void OnEventRaised() // 6 { response.Invoke(); } } 

No código mostrado acima, o projeto continua a desenvolver:

  1. Requisito para usar a classe UnityEvent.
  2. O GameEvent ao qual este GameEventListener se inscreverá.
  3. A resposta UnityEvent que será gerada quando o evento GameEvent lança este GameEventListener.
  4. Vinculando um GameEvent a um GameEventListener quando este GameObject está ativado.
  5. Vinculando um GameEvent de um GameEventListener quando este GameObject está desabilitado.
  6. Chamado quando um GameEvent é gerado que faz com que o GameEventListener chame o evento UnityEvent.

Isso é difícil? Nada, você descobrirá com o tempo!

Treinamento do Editor


Volte ao editor do Unity e crie uma nova pasta de eventos do jogo em Scripts >> ScriptableObjects. Em seguida, crie sete Eventos do jogo no menu Asset, como fizemos para cada ativo Sword Data. Coloque-os na nova pasta Game Events.


Substitua o código dentro do script Sword.cs pelas seguintes linhas:

  [SerializeField] private GameEvent OnSwordSelected; // 1 private void OnMouseDown() { OnSwordSelected.Raise(); // 2 } 

Este código adiciona duas possibilidades à loja do comerciante de espadas:

  1. Geração de Evento de Jogo ao escolher uma espada.
  2. Geração de eventos quando você clica na espada.

Salve o script. Agora, em cada Hierarchy GameObject da espada, conecte o evento OnSwordSelected correspondente.


Agora, cada espada tem um link para o evento que é acionado quando a espada é clicada.

Integração de UI


Agora você precisa fazer a interface do usuário funcionar. Nosso objetivo é exibir os dados correspondentes da espada ao clicar em cada espada.

Links da interface do usuário


Antes de atualizar a interface do usuário, você deve obter um link para cada elemento da interface do usuário. Vamos começar criando um novo script chamado SwordMerchant.cs e adicionando o seguinte código a esse novo script:

 using UnityEngine; using UnityEngine.UI; public class SwordMerchant : MonoBehaviour { [SerializeField] private Text swordName; // 1 [SerializeField] private Text description; // 2 [SerializeField] private Image icon; // 3 [SerializeField] private Text goldCost; // 4 [SerializeField] private Text attackDamage; // 5 } 

Usando esse código, adicionamos o seguinte:

  1. Uma referência ao componente de texto do objeto de jogo NameText .
  2. Link para o componente de texto do objeto de jogo DescriptionText .
  3. Link para o componente Image do objeto de jogo Sword_Icon .
  4. Link para o componente de texto do objeto de jogo GoldText .
  5. Um link para o componente Texto do objeto de jogo AttackText .

Os objetos do jogo acima estão localizados no SwordMerchantCanvas >> SwordMerchantPanel da janela Hierarquia. Adicione o script ao GameObject SwordMerchantCanvas e configure todos os links:


Ouvintes e respostas da interface do usuário


Todas as espadas têm um evento no qual a interface do usuário pode se inscrever usando o script GameEventListener . Adicione um GameEventListener para cada evento OnSwordSelected a GameObject SwordMerchantCanvas :


Como você pode ver, o nosso Event Event Listener tem dois campos: o evento do Event Game que ele escuta e a resposta que é gerada quando o Event Game é gerado.

No nosso caso, a resposta será atualizada pela interface do usuário. Adicione o seguinte método ao script SwordMerchant.cs :

  public void UpdateDisplayUI(SwordData swordData) { swordName.text = swordData.SwordName; description.text = swordData.Description; icon.sprite = swordData.Icon; goldCost.text = swordData.GoldCost.ToString(); attackDamage.text = swordData.AttackDamage.ToString(); } 

Este método recebe um ativo Sword Data e atualiza cada campo da interface do usuário com o valor do campo Sword Data correspondente. Observe que GoldCost e AttackDamage retornam um int , então você precisa convertê-lo em string para texto.

Usando nosso novo método, podemos adicionar uma resposta a cada GameEventListener .

Para cada resposta adicionada, você precisa de um link para nosso objeto de jogo SwordMerchantCanvas como o valor do campo Nenhum (Objeto) . Depois disso, selecione SwordMerchant.UpdateDisplayUI no menu suspenso à direita da lista suspensa Apenas tempo de execução .

Tenha cuidado e use o ativo Sword Data correto para todos os eventos OnSwordSelected .


Agora podemos começar o jogo, clique na espada e veja se a interface do usuário é atualizada de acordo!


Como usamos os Game Events, você pode simplesmente SwordMerchantCanvas , e tudo continuará funcionando, apenas sem uma interface do usuário. Isso significa que os prefabs da espada são separados dos SwordMerchantCanvas .

Para onde ir a seguir?


Se você perdeu alguma coisa durante a história, pode fazer o download do projeto final , que está nos materiais do tutorial.

Se você quiser seguir em frente, tente fazer com que cada espada reproduza seu próprio som. Tente expandir os Dados da Espada de Objetos OnSwordSelected e escute os eventos OnSwordSelected .

Deseja saber mais sobre o Unity? Confira nossa série de vídeos do Unity ou leia os tutoriais do Unity .

Source: https://habr.com/ru/post/pt421523/


All Articles