Inventário
Primeiro: Não é um sistema simples.
Segundo: o modelo apresentado aqui é um sistema básico, mas que pode ser adaptado para várias necessidades e jogos.
Para este exemplo irei utilizar um jogo de plataforma base, mas os conceitos aqui demostrado poderão ser utilizados em diversos tipos de jogos.
Jogo Base:
Crie uma pasta dentro de assets à Scripts para armazenar os scripts do Inventário, chame essa pasta de inventario.
Designer do Inventário
Para criar a janela do inventário, vamos adicionar um Canva à Panel. Nomeie esse Panel para Inventario.
Ajuste o painel para um tamanho adequado a um inventário de seu jogo, o meu irei definir, mas pode ser personalizado.
Veja como ficou o meu:
Adicione o componente Grid Layout Group ao inventário, configure o spacing para deixar um espaço entre os Slots.
Vamos adicionar um componente do tipo Image, que será o modelo de slot para o item no inventário.
- Adicione uma Image no Panel inventário e nomeie ele como Slot.
- Dentro do objeto Slot (Image) adicione mais um Image e renomeie como Item.
- Selecione a Image Slot e adicione um Grid Layout Group e configure conforme imagem abaixo:
- Defina o Cell size com X=60 e Y = 60 e Child Alignment –> Middle Center.
- Ainda no Slot, adicione o componente Event Trigger.
O Event Trigger, recebe eventos do sistema, como movimento do mouse, clique etc.
- Aproveite que está adicionando os componentes do Slot e configure a TAG, crie uma tag para o Slot com o nome Slot.
Scripts
Para esse sistema de inventario iremos criar cinco Scripts.Despois de criarmos, mostrarei em quais objetos serão anexados e as configurações no Inspector.
Inventario.cs à Adiciona o item no slot, verificar se tem slot vazio atualiza a imagem do item adicionado.
SlotInventario.cs à Controla o item adicionado ao slot, como funções de troca de slot e fixação do item no slot.
ArrastaItem.cs à controla o sistema de arrasto do mouse (Drag) do item entre os slots e a “Lixeira.
PegarItem.cs à Controla a sistema que adiciona o objeto em cena ao inventário.
AreaExcluir.cs à controla a exclusão do item do inventário, também pode ser adaptado para executar alguma instrução ao mover o item.
Abra o Script Inventario
Algumas mensagens de erro irão aparecer, aguarde até a configuração de todos os scripts antes de tentar corrigir, pois alguns erros são devido à ausência de códigos em alguma classe ou falta de configuração do Inspector.
Este script permite adicionar um item ao inventário. Ele verifica se há um slot vazio e, caso positivo, instancia o item no slot e configura seu visual. A função principal aqui é AdicionarItem, que realiza toda a lógica para verificar a disponibilidade de slots e adicionar o item.
- Slots no Inventário:
O inventário é composto por vários slots, que são representados por objetos Transform. Cada slot pode conter um item, e o sistema de inventário verifica qual slot está vazio para adicionar um novo item. - AdicionarItem:
A função principal do inventário é adicionar um item a um slot vazio. Ela faz isso ao:- Iterar sobre os slots.
- Verificar se o slot está vazio.
- Instanciar o item no slot vazio.
- Configurar o slot como o “parent” do item.
- Atualizar o sprite visual do item no inventário para que ele apareça corretamente.
- Controle Visual e Funcional:
- O item é visualmente atualizado com a imagem (sprite) correta.
- O script ArrastaItem é configurado para que o item possa ser arrastado e solto de volta ao inventário.
Fluxo de Execução:
- O usuário tenta adicionar um item ao inventário.
- O método AdicionarItem percorre os slots e verifica se há um disponível.
- Se encontrar um slot vazio, ele instancia o item no slot, atualiza o sprite e retorna true.
- Se todos os slots estiverem ocupados, ele retorna false, indicando que o inventário está cheio.
Explicação:
Importação de Bibliotecas
UnityEngine.UI: Esta biblioteca fornece classes e métodos para manipular elementos de interface do usuário (UI), como botões, imagens e textos. Neste caso, ela é necessária para manipular o componente Image dos itens.
Declaração da Classe
- Inventario: Esta é a classe responsável por gerenciar os slots do inventário e os itens que são adicionados a eles.
- slots: Um array de Transform que armazena referências aos slots do inventário. Cada slot é representado por um Transform, o que permite que novos itens sejam instanciados dentro desses slots.
Função AdicionarItem
- Parâmetros:
- itemPrefab (GameObject): O prefab do item que será adicionado ao inventário. O prefab é uma referência a um modelo predefinido do item que será instanciado.
- itemSprite (Sprite): O sprite que será usado como a imagem visual do item no inventário. Isso personaliza a aparência do item.
Iteração pelos slots:
O método percorre cada slot do inventário usando um laço foreach. A variável slot representa cada slot individual do inventário durante a iteração.
Verificação de slot vazio:
Verifica se o slot está vazio. A propriedade childCount retorna o número de objetos filhos que o slot tem. Se for igual a 0, significa que o slot está vazio e, portanto, pode receber um novo item.
Instanciação do item:
Se o slot estiver vazio, o método Instantiate é chamado para criar uma instância do itemPrefab dentro desse slot. Isso cria uma cópia do prefab e a coloca como filha do Transform do slot, ou seja, o item será posicionado dentro do slot na hierarquia da UI.
Atribuição do parent:
Após instanciar o item no slot, o script acessa o componente ArrastaItem (que controla o arrastar e soltar do item) e define o parentDepoisArrastar como o slot atual. Isso garante que, caso o item seja arrastado e solto novamente, ele saiba qual era o seu slot original.
Atualização da imagem do item:
Aqui, o script acessa o componente Image do item recém-criado para alterar o sprite (imagem) exibido no inventário.
Verifica se o componente Image existe (itemImage != null) e se o sprite fornecido também não é nulo. Se ambos forem válidos, o sprite do item é atualizado para a imagem do objeto no inventário.
Retorna verdadeiro se o item foi adicionado com sucesso:
Quando o item é adicionado com sucesso a um slot, o método retorna true, indicando que o processo foi concluído sem problemas.
Caso não haja slots vazios:
Se o laço foreach não encontrar nenhum slot vazio (ou seja, todos os slots têm itens), o método retorna false, indicando que o inventário está cheio e o item não pôde ser adicionado.
Abra o Script, PegarItem.
Este script detecta quando o jogador clica em um item no mundo do jogo (no caso, um objeto com um SpriteRenderer), e tenta adicioná-lo ao inventário. Se o inventário tiver espaço, o item é adicionado e removido da cena; caso contrário, uma mensagem é exibida informando que o inventário está cheio.
Funcionamento
- Início do Jogo:
- O script busca referências ao inventário (Inventario) e ao sprite (SpriteRenderer) do item.
- Interação do Jogador:
- Quando o jogador clica no item na cena (que tem esse script anexado), o método OnMouseDown é chamado.
- Adicionar Item ao Inventário:
- O script tenta adicionar o item ao inventário usando o método AdicionarItem. Se houver um slot vazio, o item é adicionado.
- Remoção do Item da Cena:
- Se o item for adicionado ao inventário com sucesso, ele é removido da cena. Caso contrário, uma mensagem é exibida no console dizendo que o inventário está cheio.
Fluxo de Execução:
- O jogador clica em um item na cena.
- O método OnMouseDown é chamado, verificando se o inventário e o sprite do item estão prontos.
- O script tenta adicionar o item ao inventário.
- Se o item for adicionado com sucesso:
- O item é removido da cena com Destroy.
- Se o inventário estiver cheio:
- Uma mensagem de erro é exibida no console, indicando que não há mais espaço no inventário.
Explicação:
Declaração da Classe
- itemPrefab: Um GameObject público que representa o prefab do item. Esse prefab será instanciado no inventário.
- inventario: Uma referência privada ao componente Inventario, que gerencia o inventário do jogador.
- spriteRenderer: Uma referência privada ao SpriteRenderer do item, usada para acessar a sprite (imagem) que será exibida no inventário.
Método Start
- FindObjectOfType<Inventario>(): Este método procura e atribui ao campo inventario uma referência ao componente Inventario presente na cena. Isso é essencial para que o script possa interagir com o sistema de inventário.
- GetComponent<SpriteRenderer>(): Acessa o componente SpriteRenderer do objeto ao qual este script está anexado. Esse componente é responsável por exibir a imagem do item na cena. A sprite desse componente será usada como a imagem do item no inventário.
Essas duas atribuições acontecem no método Start, que é chamado uma vez no início do ciclo de vida do objeto, garantindo que o script tenha as referências necessárias logo no começo.
Método OnMouseDown
- OnMouseDown(): Este método é chamado automaticamente quando o usuário clica com o botão do mouse sobre o GameObject ao qual o script está anexado. Isso faz parte do sistema de eventos de entrada do Unity, onde OnMouseDown detecta cliques em objetos que possuem um Collider.
- Verificação do Inventário e do Sprite:
if (inventario != null && spriteRenderer != null)
O script primeiro verifica se as referências ao inventario e ao spriteRenderer foram corretamente obtidas no método Start. Se qualquer uma dessas referências for nula, o código não prossegue.
- Tentativa de Adicionar o Item ao Inventário:
bool itemAdicionado = inventario.AdicionarItem(itemPrefab, spriteRenderer.sprite);
Se o inventário e o sprite estiverem configurados corretamente, o script chama o método AdicionarItem da classe Inventario, passando o itemPrefab (o prefab do item) e a sprite (spriteRenderer.sprite) como argumentos.
O método AdicionarItem tentará encontrar um slot vazio no inventário e, se houver, adicionará o item. O resultado dessa operação será armazenado em itemAdicionado, que será true se o item for adicionado com sucesso, ou false se o inventário estiver cheio.
- Destruição do Item na Cena:
if (itemAdicionado)
{
Destroy(gameObject);
}
Se itemAdicionado for true, o item na cena (representado por gameObject) será destruído. A função Destroy(gameObject) remove o objeto do jogo, simulando o “pegamento” do item pelo jogador.
- Exibição de Mensagem Quando o Inventário Está Cheio:
else
{
Debug.Log(“Inventário cheio! Não é possível adicionar mais itens.”);
}
Se o inventário estiver cheio (ou seja, itemAdicionado for false), o script exibe uma mensagem no console usando Debug.Log, informando ao desenvolvedor que o inventário não tem mais espaço.
Agora vamos editar o Script ArrastaItem.
- Objetivo: A classe ArrastaItem permite que itens sejam arrastados e soltos dentro de um inventário em um jogo ou interface de usuário.
- Funcionamento:
- No início do arrasto, o script guarda a posição original do item.
- Enquanto o item está sendo arrastado, ele segue o cursor do mouse.
- Quando o arrasto termina, o item é colocado de volta no seu slot original ou em um novo slot, se o jogador o soltou sobre um local válido.
- Controle visual: A posição visual do item é manipulada para garantir que ele seja renderizado corretamente e que eventos de interação (como cliques) não interfiram enquanto o item está sendo arrastado.
A classe implementa três interfaces da Unity, que lidam com eventos de arrastar:
- IBeginDragHandler: Captura o evento no início do arrasto.
- IDragHandler: Captura o evento durante o arrasto.
- IEndDragHandler: Captura o evento no final do arrasto.
Importações de Bibliotecas
Declaração da Classe
- ArrastaItem: É um script que será anexado a um item do inventário.
- A classe implementa as interfaces mencionadas para capturar os eventos de arrastar.
Variáveis
parentDepoisArrastar:
Tipo: Transform
Armazena o parent original (ou slot) do item antes de ele ser arrastado. Quando o item é arrastado, ele pode ser movido para outro local, mas no final, ele precisa ser reposicionado em um novo slot ou no slot original.
image:
Tipo: Image
Refere-se ao componente de imagem do item na UI. Isso é usado para manipular a aparência visual do item, como desabilitar ou reabilitar a detecção de cliques (raycasting) enquanto o item está sendo arrastado.
Método OnBeginDrag
Este método é chamado quando o jogador começa a arrastar o item.
parentDepoisArrastar = transform.parent:
Armazena o transform (referência ao slot) original do item antes de começar a arrastar. Isso permite que, se o item não for solto em um local válido, ele possa ser retornado ao seu slot original.
transform.SetParent(transform.root):
Quando o item é arrastado, ele é removido do seu slot atual e colocado no topo da hierarquia (transform.root), permitindo que ele seja exibido acima de todos os outros elementos da interface. Isso garante que o item seja visível enquanto é movido.
transform.SetAsLastSibling():
Esta linha coloca o item no topo da pilha de renderização, garantindo que ele apareça acima de todos os outros objetos visuais da UI enquanto é arrastado.
image.raycastTarget = false:
Desativa temporariamente o raycastTarget, o que significa que o item não detectará interações de clique enquanto está sendo arrastado. Isso evita que o item bloqueie a detecção de outros eventos, como o “drop” em um slot válido.
Método OnDrag
Este método é chamado continuamente enquanto o jogador arrasta o item.
transform.position = Input.mousePosition:
- Enquanto o item está sendo arrastado, sua posição é atualizada para seguir a posição do mouse. Isso permite que o jogador arraste o item pela tela livremente. O método Input.mousePosition captura a posição do cursor na tela.
Método OnEndDrag
Este método é chamado quando o jogador solta o item, indicando o final do arrasto.
- EventSystem.current.IsPointerOverGameObject():
Verifica se o mouse está sobre um objeto da interface de usuário (UI). Isso é importante para determinar se o jogador está soltando o item em um slot válido de inventário ou apenas em qualquer área da tela.
- eventData.pointerEnter:
pointerEnter captura o objeto da UI que está sob o ponteiro do mouse no momento em que o jogador solta o item. Isso ajuda a determinar se o item foi solto em um slot ou em outra parte da interface.
- Verifica se o objeto é um slot válido:
objetoAbaixo.transform.parent.CompareTag(“SlotInventario”):
Esta linha verifica se o item foi solto sobre um slot de inventário. Se o objeto abaixo do ponteiro tiver a tag “SlotInventario”, significa que o item foi solto em um local válido.
Se for o caso, parentDepoisArrastar é atualizado para o novo slot (objetoAbaixo.transform).
- transform.SetParent(parentDepoisArrastar):
Depois de soltar o item, ele é reposicionado no seu novo slot, se houver um. Se o jogador não tiver soltado o item em um slot válido, ele será retornado ao seu parent original.
- image.raycastTarget = true:
Reativa o raycastTarget, permitindo que o item volte a detectar eventos de clique após ser solto. Agora o item pode novamente interagir com outros elementos da UI.
Script Slot Inventário
Esse script controla o comportamento dos slots do inventário, utilizando o sistema de arrastar e soltar do Unity. Ele implementa a interface IDropHandler, que permite que o slot receba notificações quando um item é “solto” sobre ele. Basicamente, o script verifica se o slot está vazio e, se estiver, ele aceita o item que foi arrastado.
Funcionamento
- Receber o item arrastado: Quando o jogador solta um item sobre o slot, o método OnDrop é chamado, trazendo consigo as informações do objeto que foi arrastado.
- Verificação de slot vazio: O slot verifica se está vazio (se não contém nenhum outro item). Se o slot já tiver um item, ele não aceitará o novo item arrastado.
- Posicionar o item: Se o slot estiver vazio, ele aceita o item arrastado, alterando o parentDepoisArrastar do item para si mesmo, o que indica que o item agora pertence a esse slot.
Fluxo de Execução
- O jogador arrasta um item na interface do inventário.
- Quando o jogador solta o item sobre um slot, o método OnDrop do slot é chamado.
- O slot verifica se está vazio. Se estiver, ele aceita o item.
- O slot altera o parentDepoisArrastar do item, indicando que o item agora está nesse slot.
- O item fica ancorado nesse novo slot até que o jogador o arraste novamente.
Declaração da Classe
- SlotInventario: Essa é a classe que representa um slot no inventário.
- IDropHandler: A interface IDropHandler é implementada para permitir que o slot detecte quando um item é solto nele. Isso faz parte do sistema de eventos do Unity, permitindo que o componente receba notificações quando o jogador realiza a ação de soltar um item.
Método OnDrop
Recebe o evento de soltar o item:
Esse método é chamado automaticamente quando o jogador solta um item sobre o slot. O parâmetro eventData contém informações sobre o evento de soltar, incluindo qual item foi arrastado e onde ele foi solto.
Verifica se o slot está vazio
transform.childCount: Esse código verifica se o slot já contém algum item. No Unity, o transform do slot é a estrutura hierárquica onde o objeto do item é “filho” do slot. Se childCount for igual a 0, significa que o slot está vazio e pode receber um novo item.
Obtém o item arrastado
eventData.pointerDrag: O Unity mantém uma referência ao objeto que foi arrastado pelo jogador, armazenado em pointerDrag. Nesse caso, dropped é o GameObject que o jogador estava arrastando e soltou sobre o slot.
Acessa o script ArrastaItem do item
dropped.GetComponent<ArrastaItem>(): Após obter o objeto arrastado, o script tenta acessar o componente ArrastaItem, que é responsável por permitir que o item seja arrastado. Esse script contém informações importantes, como o slot original do item.
Define o novo parent do item
parentDepoisArrastar: Esse campo em ArrastaItem define onde o item será “anexado” após o arrasto. Aqui, o código define o parentDepoisArrastar como o transform do slot atual (que está recebendo o item).
Ao alterar o parentDepoisArrastar, o item é posicionado no novo slot quando o jogador termina de arrastar, fazendo com que o item “fique” no novo slot.
Script AreaExcluir
Esse script permite que uma área na interface funcione como uma “lixeira”, onde os itens podem ser deletados ao serem arrastados e soltos nela. Ele também muda a cor da lixeira quando o mouse passa por cima, para fornecer um feedback visual ao jogador.
Funcionamento
- Deletar itens: Quando o jogador arrasta um item e o solta na lixeira, o método OnDrop é chamado, e o item é deletado da cena com Destroy.
- Mudança de cor ao passar o mouse: Quando o ponteiro do mouse entra na área da lixeira, a cor da lixeira muda para vermelho, sinalizando que o jogador pode excluir itens. Quando o mouse sai da área, a cor volta ao normal.
Fluxo de Execução
- O jogador arrasta um item e passa sobre a lixeira. A cor muda para vermelho (indicando que pode soltar o item).
- Se o jogador soltar o item na lixeira, o método OnDrop é chamado, o item é deletado e uma mensagem é registrada no console.
- Quando o jogador tira o ponteiro da lixeira, a cor volta ao normal.
Importação de Bibliotecas
- UnityEngine.UI: Inclui componentes de UI, como Image, que são usados para a representação gráfica de elementos na interface.
- UnityEngine.EventSystems: Essa biblioteca é necessária para trabalhar com os eventos de interface de usuário, como quando um objeto é arrastado e solto (IDropHandler) ou quando o ponteiro do mouse entra ou sai de uma área (IPointerEnterHandler e IPointerExitHandler).
Declaração da Classe
- AreaExcluir: Essa classe representa a área da lixeira.
- IDropHandler: Interface que permite capturar eventos de “soltar” (drop) quando um item é solto na lixeira.
- IPointerEnterHandler: Interface para capturar eventos quando o ponteiro do mouse entra na área da lixeira.
- IPointerExitHandler: Interface para capturar eventos quando o ponteiro do mouse sai da área da lixeira.
Essas interfaces permitem que o script manipule eventos de arrastar e soltar, além de eventos relacionados ao movimento do ponteiro do mouse sobre a área da lixeira.
Variáveis e Método Start
- private Image image: Armazena a referência ao componente Image associado à lixeira. Isso é necessário para alterar a cor da lixeira quando o ponteiro do mouse entra ou sai da área.
- Start(): No método Start, o componente Image da lixeira é obtido usando GetComponent<Image>(). Isso é feito apenas uma vez, quando o objeto que contém o script é inicializado.
Método OnDrop
Este método é responsável por deletar o item que é solto na área da lixeira.
1. Recebe o evento de soltar o item
public void OnDrop(PointerEventData eventData)
- Esse método é chamado automaticamente quando o jogador solta um item sobre a área da lixeira. O eventData contém informações sobre o evento, incluindo qual item foi arrastado.
2. Obtém o item arrastado
GameObject itemArrastado = eventData.pointerDrag;
- eventData.pointerDrag: Esta propriedade contém uma referência ao objeto que foi arrastado e está sendo solto na lixeira. O objeto é armazenado na variável itemArrastado.
3. Verifica se o item arrastado é válido
if (itemArrastado != null)
- Antes de tentar deletar o item, o script verifica se itemArrastado não é null, ou seja, se o jogador realmente soltou algo na lixeira.
4. Deleta o item
Destroy(itemArrastado);
- Destroy(itemArrastado): Esta função remove o item da cena, efetivamente deletando-o. Quando o item é destruído, ele não aparece mais no jogo.
5. Log de depuração
Debug.Log(“Item deletado na lixeira”);
- Este comando envia uma mensagem ao console do Unity para fins de depuração, indicando que o item foi deletado na lixeira.
Método OnPointerEnter
Este método é chamado quando o ponteiro do mouse entra na área da lixeira. Ele altera a cor da lixeira para vermelho como um indicativo visual de que o jogador pode soltar um item ali.
1. Captura a entrada do ponteiro
public void OnPointerEnter(PointerEventData eventData)
- Esse método é executado sempre que o ponteiro do mouse entra na área da lixeira. O eventData contém informações sobre o evento, mas neste caso, ele não é utilizado.
2. Muda a cor da lixeira
image.color = Color.red;
- O componente Image da lixeira tem sua cor alterada para vermelho quando o ponteiro do mouse entra na área, indicando que o jogador pode soltar itens para deletá-los.
Método OnPointerExit
Este método é chamado quando o ponteiro do mouse sai da área da lixeira. Ele restaura a cor original da lixeira, removendo o indicativo de que um item pode ser solto.
1. Captura a saída do ponteiro
public void OnPointerExit(PointerEventData eventData)
- Esse método é executado quando o ponteiro do mouse sai da área da lixeira.
2. Restaura a cor original
image.color = Color.white;
- Quando o mouse sai da área da lixeira, a cor da lixeira volta ao branco (ou à cor original da imagem), indicando que a área de exclusão não está mais ativa.