Sistema de Diálogo Simples

Sistema de Diálogo (uma das muitas versões por ai!)

O Scriptable Object.

Scriptable Objects são classes que você pode instanciar no projeto como se fossem assets!

São objetos personalizados que permitem armazenar e compartilhar dados entre diferentes instâncias de objetos.

Armazenam os dados em variáveis declaradas dentro do script, os Scriptable Objects são objetos independentes. E que podem ser criados e modificados em tempo de execução, pois, não estão em cena como os scripts. Por isso, podem ser usados para armazenar dados que precisam ser acessados globalmente, como configurações, dados de inventário etc.

Ao contrário dos scripts “normais” que herdam de MonoBehaviours, que geralmente vinculados a objetos de jogo em cena, os Scriptable herdam da classe Scriptable.

Mãos à obra!!

  • Em seu projeto crie uma pasta chamada Diálogo dentro de Assets, essa pasta é para organizar os diálogos.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

  • Dentro da pasta Dialogo, crie um script C# chamado Personagem, esse script irá armazenar os dados do nosso personagem, como nome e imagem do avatar, nesse exemplo iremos armazenar poucos dados, mas você poderá armazenar mais informações como idade, XP, HP, posição etc.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

  • Abra a classe Personagem edite conforme imagem abaixo: Remova os métodos Start e Update (não iremos utilizar), muda a herança MonoBehaviour para a classe Scriptable.

Texto

Descrição gerada automaticamente com confiança média

Após a modificação.

Texto

Descrição gerada automaticamente

Vamos lá:

  1. using UnityEngine;
    1. Esse comando importa o namespace UnityEngine, que contém classes e funções necessárias para o desenvolvimento em Unity, como MonoBehaviour, GameObject, Transform, entre outros. Ele é essencial para usar muitos dos componentes nativos da Unity.
  2. [CreateAssetMenu(fileName=”Novo_Personagem”, menuName=”Dialogo/Personagem”)]
    1. Essa linha é um atributo que permite que a Unity crie um item no menu “Create” para gerar instâncias desse ScriptableObject do no editor da Unity.
    2. fileName: O nome padrão para o arquivo quando um novo ScriptableObject desse tipo for criado.
    3. menuName: O nome e caminho no menu do editor para criar esse ScriptableObject. Neste caso, ele aparecerá como “Dialogo/Personagem”.
    4. Explicação prática: No Unity Editor, ao clicar com o botão direito no painel do Project, você verá a opção Dialogo > Personagem. Ao clicar, será criado um arquivo ScriptableObject com o nome padrão Novo_Personagem.
  3. public class Personagem: ScriptableObject
    1. Aqui você está declarando uma classe chamada Personagem que herda de ScriptableObject. Um ScriptableObject é um tipo de classe no Unity que é usada para armazenar dados independentes de cenas ou GameObjects, ideal para criar dados reutilizáveis, como definições de personagens, configurações etc. No seu caso, você está criando uma classe para armazenar os dados de um personagem.
  4. public string NomePersonagem;
    1. Define uma variável pública do tipo string chamada NomePersonagem. Essa variável será usada para armazenar o nome do personagem.
    2. Como ela é pública, você pode definir o nome do personagem diretamente no Inspector da Unity ao criar uma instância desse Scriptable Object.

Exemplo: Você pode colocar o nome “Herói” ou “Vilão” como valor para essa variável no Inspector.

  1. public Sprite[] expressoesPersonagem;
    1. Define um array (lista) pública de Sprites chamado expressoesPersonagem.
    2. Sprites são imagens 2D, comumente usadas para representar personagens ou outros elementos gráficos no Unity.

Este array armazenará diferentes expressões do personagem (como “feliz”, “triste”, “zangado”, etc.), possibilitando que você associe imagens diferentes para representar emoções.

Funcionamento do Código:

Esse código cria um Scriptable Object que pode ser usado para armazenar informações sobre um personagem em um sistema de diálogo, incluindo seu nome e suas expressões faciais (em forma de Sprites). Essas informações podem ser configuradas diretamente no Editor da Unity e usadas em sistemas que precisem acessar dados dos personagens, como cenas de diálogo ou interações com o jogador.

Criando os Objeto

Inicialmente iremos criar três Personagens. Dica: Ao criar um sistema de diálogo, faça o texto como se fosse para uma peça de teatro, onde definimos os personagens, expressões e suas falas durante a peça.

      1. Dentro da pasta Dialogo clique com o botão direito (em qualquer lugar dentro da pasta), irá aparecer o menu de contexto, selecione Create Dialogo Personagem.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

      1. Renomeie o arquivo criado como Player

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

      1. Selecione o Objeto Player e vamos editar seus dados no Inspector:

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

Aqui preenchemos os dados que definimos como características do personagem, como Nome do Personagem e suas expressões. Vou utilizar alguns Sprites Free da internet. No exemplo utilizei apena um sprite, mas você pode adicionar novas imagens clicando no botão + ou excluir sprite no botão .

Crie mais dois objetos, pode nomear como NPC1 e NPC2, lembre-se de adicionar um sprite parar exibir a imagem do Personagem na caixa de diálogo.

Interface gráfica do usuário, Aplicativo, Teams

Descrição gerada automaticamente

OK já criamos nossos personagens, agora vamos criar as falas entre os personagens.

Primeiro vamos criar o Scriptable que irá armazenar os diálogos entre os personagens, o script do diálogo.

  1. Crie um script na pasta de Dialogo. Vamos Chama-lo de Dialogo.

Interface gráfica do usuário, Aplicativo, Teams

Descrição gerada automaticamente

  1. Abra o Script e edite conforme a imagem abaixo:

Texto

Descrição gerada automaticamente

Criando um diálogo

  1. Agora vamos criar nossos objetos que irão contêm as falas entre os personagens. Clique com o botão direito dentro da pasta Dialogo à Create àDialogoàDialogos

Interface gráfica do usuário

Descrição gerada automaticamente

  1. Nomeie como PlayerNPC1, pois irá armazenar as conversas entre o player e o npc1.
  2. Selecione o objeto PlayerNPC1, e edite ele no inspector. Irei criar um diálogo simples.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

    1. Expanda o item Falas.
    2. Para adicionar um diálogo, clique no sinal + para adicionar.
    3. Expanda o item Element. Nele podemos encontrar os itens:

Personagem: Aqui definimos qual personagem está falando. Clique no ícone , irá abrir uma caixa de diálogo com os elementos da pasta Diálogo, selecione o Player (personagem).

Id Expressao : Selecione qual imagem do avatar será exibido, lembra da lista de expressões no Objeto personagem.

Texto das Falas: Clique no sinal de + para adicionar uma frase, podemos adicionar mais de uma frase.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

Para Adicionar no segundo sinal de +.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

Monte seus diálogos.

Agora vamos criar a caixa de diálogo. Para isso vamos criar um CANVAS com um painel, uma imagem e duas caixas de texto.

Para evitar dores de cabeça, como textos fora de lugar, distorções por conta de resoluções diferentes, ajuste o tamanhão do canvas, pode ser para HD ou Full HD, na imagem abaixo usaremos o Full HD.

Interface gráfica do usuário

Descrição gerada automaticamente

Primeiro vamos adicionar um Painel (Panel).

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

Renomeie para CaixaDialogo.

Ajuste o React para Button/Center.

Tela de computador com jogo

Descrição gerada automaticamente

Dimensione o Panel para que ocupe apenas uma parte da tela de jogo. O exemplo abaixo é apenas para referência.

Interface gráfica do usuário

Descrição gerada automaticamente

Dentro do Panel (caixaDialogo) insira um Image, Um Button e dois TextMeshPro. Procure deixar como a imagem abaixo, mas poderá personalizar.

Renomeie os Text Mesh Pro (ao adicionar um Text Mesh, não esqueça de importar as bibliotecas), uma será o textoNome e o outro TextoFala.

Renomeie o button para proximaFala.

Interface gráfica do usuário, Site

Descrição gerada automaticamente

Selecione O Panel (CaixaDialogo) na Hierarquia e desabilite ele no Inspector.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

Voltemos aos Scripts agora.

Abra a pasta dos scripts do Diálogo e crie um Script chamado ControleDialogo. Esse script será responsável pelo controle de exibição e carregamento dos diálogos.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

Crie um GameObject na Hierarchy chamado ControleDialogo e anexe o Script nesse objeto.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

Texto

Descrição gerada automaticamente

Texto

Descrição gerada automaticamente

Onde:

Texto

Descrição gerada automaticamente

  • System.Collections e System.Collections.Generic: Incluem as classes para trabalhar com coleções, como listas e filas (Queue). Aqui, você usará Queue e foreach.
  • UnityEngine: Importa a API da Unity para permitir interação com componentes de jogos e elementos de interface.
  • UnityEngine.UI: Necessário para trabalhar com componentes de interface do usuário, como GameObject e Image.
  • TMPro: Importa a biblioteca TextMeshPro, usada para renderizar textos com qualidade superior no Unity, como o TextMeshProUGUI.

Classe ControleDialogo:

Esta classe ControleDialogo herda de MonoBehaviour, o que permite que ela seja atribuída a um objeto no Unity como um script de controle de diálogo para o jogo.

Variáveis da caixa de diálogo:

Texto

Descrição gerada automaticamente

  • caixaDialogo: Um objeto que representa a caixa de diálogo no jogo. Você pode ativar e desativar essa caixa com SetActive() para exibir ou esconder a interface.
  • expressaoPersonagem: Um componente de imagem que mostra a expressão facial do personagem. Ele muda conforme o diálogo progride.
  • nomePersonagem: Um texto de interface que exibe o nome do personagem falando no momento, usando TextMeshPro.
  • falaPersonagem: Outro texto de interface que exibe a fala atual do personagem, também usando TextMeshPro.

Variáveis de controle do sistema de diálogo:

Texto

Descrição gerada automaticamente

  • dialogoAtual: Um objeto da classe Dialogos que contém todos os diálogos atuais para serem exibidos. Esse objeto provavelmente possui uma lista de falas e informações sobre os personagens.
  • indice: Um contador que rastreia qual fala ou diálogo está sendo exibido atualmente.
  • filaDialogo: Uma fila (Queue<string>) de falas que serão exibidas na caixa de diálogo, permitindo processar e exibir uma fala de cada vez.

Método iniciarDialogo:

Texto

Descrição gerada automaticamente

iniciarDialogo(Dialogos dialogo): Um método público que inicia o diálogo, ativando a caixa de diálogo e inicializando variáveis.

  • caixaDialogo.SetActive(true): Ativa o GameObject da caixa de diálogo.
  • filaDialogo = new Queue<string> (): Inicializa a fila para armazenar as falas do diálogo.
  • dialogoAtual = dialogo: Atribui o diálogo passado como argumento ao dialogoAtual.
  • indice = 0: Inicializa o índice do diálogo para 0, indicando o início do diálogo.
  • proximoDialogo(): Chama o método para carregar a primeira fala do diálogo.

Texto

Descrição gerada automaticamente

Método proximoDialogo:

  1. if (filaDialogo.Count == 0): Verifica se todas as falas na fila atual foram exibidas. Se a fila estiver vazia, isso indica que é hora de carregar novas falas.
  2. if (indice < dialogoAtual.falas.Length): Verifica se ainda há falas restantes no diálogo atual (com base no índice). Se sim, ele procede para carregar a próxima fala.
  3. Carregamento da expressão do personagem:
    • expressaoPersonagem.sprite: Atribui ao componente de imagem a expressão facial do personagem, baseada no índice da fala e no Id da expressão.
    • SetNativeSize(): Ajusta o tamanho da imagem da expressão para o seu tamanho original.
  4. Carregamento do nome do personagem:
    • nomePersonagem.text: Atualiza o nome do personagem que está falando.
  5. Laço para carregar as falas:
    • foreach (string textoFalas in dialogoAtual.falas[indice].textoFalas): Percorre todas as falas que o personagem tem para a cena atual e as coloca na fila usando Enqueue.
  6. Incremento do índice:
    • indice++: Após carregar as falas e a expressão, o índice é incrementado para passar para a próxima fala na próxima vez que proximoDialogo() for chamado.
  7. Desativação da caixa de diálogo:
    • caixaDialogo.SetActive(false): Se não houver mais falas, a caixa de diálogo é desativada, sinalizando que o diálogo acabou.
  8. Exibição da próxima fala:
    • falaPersonagem.text = filaDialogo.Dequeue(): A próxima fala na fila é exibida no TextMeshProUGUI da fala do personagem.

Este sistema permite gerenciar o diálogo entre personagens de forma organizada, carregando as expressões, nomes e falas de acordo com o diálogo que está ocorrendo, em um fluxo que progride fala por fala.

Agora Vamos configurar o Objeto ControleDialogo. Como a imagem abaixo:

Gráfico

Descrição gerada automaticamente

Pronto, o sistema de diálogo está montado, só falta decidir de qual forma será acionado.

  • Neste exemplo irei utilizar um player que ao se aproximar de um “NPC” irá acionar o sistema de diálogo através do Colliders, mas pode se utilizar por exemplo o KeyPress, ou outra foram que se adeque mais a sua mecânica.
  • Adicionei dois personagens NPC´s com Colliders em Is Trigger (não precisa estar is trigger, depende da mecânica adotada). Veja minha cena(exemplo):

Tela de computador com jogo

Descrição gerada automaticamente

Vamos criar um Script para o NPC, irei fazer o NPC1 primeiro.

Na pasta Scripts, crie um script C# chamado NPC e anexe ao NPC1.

Interface gráfica do usuário

Descrição gerada automaticamente

Edite o Script do NPC.

Texto

Descrição gerada automaticamente

Onde:

  • public ControleDialogo controle; Esta variável pública referência um outro script chamado ControleDialogo. Esse script gerencia a lógica de exibição e funcionamento dos diálogos no jogo. Como ela é pública, você pode atribuir o controlador de diálogo diretamente no Inspector da Unity.
  • public Dialogos dialogo; Este é outro script ou classe que contém os dados do diálogo que o NPC deve exibir (como as falas ou a sequência de falas). Assim como a variável anterior, ela pode ser atribuída no Inspector.
  • OnTriggerEnter2D(Collider2D col): Este é um método de detecção de colisão que será chamado quando um objeto com Collider2D atravessar a área de colisão (trigger) do NPC.
  • Collider2D col: Representa o objeto que entrou na área de colisão do NPC. A variável col é do tipo Collider2D e contém informações sobre o objeto que causou a colisão.
  • if(col.gameObject.tag==”Player”): Verifica se o objeto que entrou em colisão tem a tag “Player”. A tag é uma maneira de identificar facilmente diferentes tipos de objetos no jogo. Neste caso, ele está verificando se foi o jogador quem entrou em contato com o NPC.
  • controle.iniciarDialogo(dialogo): Se a condição for verdadeira (ou seja, se o jogador encostar no NPC), este comando é executado. Ele chama o método iniciarDialogo do script ControleDialogo, passando o diálogo correspondente que está associado ao NPC. Isso inicia o diálogo quando o jogador colide com o NPC.

Configurando o Inspector do NPC1:

No Inspector expanda o NPC (Script) e configure os seguintes itens:

  • Controle : é o Objeto na Hierarquia Controle Dialogo .
  • Dialogo: é a classe PlayerNPC1 que criamos na pasta Dialogo em assets.

Voce pode clicar no ircone no canto da caixa do item para abria as caixas de dialogos correspondentes.

Tela de computador com texto preto sobre fundo branco

Descrição gerada automaticamente

Selecione O Button ProximaFala, que está no Panel dentro do Canva.

No Inspector Configure o On Click().

Adicione o Objeto ControleDialogo e selecione o método à ControleDialogo à próximo Dialogo.

Interface gráfica do usuário, Aplicativo

Descrição gerada automaticamente

Agora Teste em seu projeto.