O Problema do “Hardcode”
Se você está criando seus inimigos (ou jogador) e definindo a vida máxima direto no script do MonoBehaviour, você está criando uma armadilha para você mesmo.
Qualquer mudança exige que você “cace” todos os prefabs que usam aquele script e ajuste os valores no Inspector. É um pesadelo de manutenção.
A solução é separar os dados (atributos) da lógica (comportamento).
- A lógica (
MonoBehaviour): “O que acontece quando tomo dano?” - Os dados (
ScriptableObject): “Quanta vida máxima eu tenho?”
Vamos construir isso.
Mas o que é um ScriptableObject?
Pense nele como um contêiner de dados ou um “molde”.
A grande diferença: um MonoBehaviour precisa estar “vivo” em um GameObject dentro de uma Cena. Um ScriptableObject não. Ele é um Asset no seu projeto, que nem uma textura ou um arquivo de áudio.
Isso significa que você pode criar vários assets de “molde” a partir de um único script. E é aí que a mágica acontece.
Passo 1: Criando o “Molde” (O Scriptable Object)
Primeiro, crie um novo script C#. Vamos chamá-lo de StatsPersonagemSO.
Abra o script e apague tudo. Substitua por este código:
using UnityEngine;
// O pulo do gato: Isso permite criar "assets" desse script no menu da Unity
[CreateAssetMenu(fileName = "NovoStatsPersonagem", menuName = "PERAI DEV/Stats Personagem")]
public class StatsPersonagemSO : ScriptableObject
{
[Header("Stats Básicas")]
public float vidaMaxima = 100f;
public float velocidadeMovimento = 5f;
public float danoAtaque = 10f;
// Você pode adicionar o que quiser aqui:
// public float defesa = 5f;
// public Color corDoPersonagem = Color.white;
}
O que fizemos aqui?
- Mudamos
MonoBehaviourparaScriptableObject. Isso diz à Unity que este é um contêiner de dados. - Adicionamos o
[CreateAssetMenu(...)]. Isso é o que nos permite criar os “moldes” clicando com o botão direito na pasta Assets (Assets > Create > PERAI DEV > Stats Personagem).
Passo 2: O Comportamento (O MonoBehaviour)
Agora, precisamos de um script que use esse molde. Este sim será um MonoBehaviour normal, que vai em um GameObject.
Crie um novo script chamado SistemaDeVida.
using UnityEngine;
public class SistemaDeVida : MonoBehaviour
{
// O campo para "encaixar" o nosso molde (a peça de Lego)
public StatsPersonagemSO statsBase;
// A vida atual é PRIVADA. Ela é única para esta instância.
private float vidaAtual;
void Start()
{
// Ao iniciar, ele "lê" o molde e define sua vida atual.
InicializarVida();
}
public void InicializarVida()
{
if (statsBase != null)
{
vidaAtual = statsBase.vidaMaxima;
}
}
public void TomarDano(float dano)
{
if (vidaAtual <= 0) return; // Já está morto
vidaAtual -= dano;
Debug.Log(gameObject.name + " tomou " + dano + " de dano. Vida restante: " + vidaAtual);
if (vidaAtual <= 0)
{
vidaAtual = 0;
Morrer();
}
}
private void Morrer()
{
Debug.Log(gameObject.name + " morreu!");
// Coloque aqui sua lógica de morte:
// Destroy(gameObject);
// ou
// GetComponent<Animator>().SetTrigger("Morrer");
}
// Apenas para testar no Inspector
[ContextMenu("Testar: Tomar 10 de Dano")]
private void TestarDano()
{
TomarDano(10);
}
}
Análise Rápida e Importante:
- Note que a
vidaAtualéprivatee fica noSistemaDeVida. - Por quê? O
ScriptableObject(o molde) é compartilhado. Se 10 Goblins usarem o mesmo asset “Stats_Goblin”, você não quer que, ao acertar um, avidaAtualde todos diminua. - O SO define a
vidaMaxima(a regra), e oMonoBehaviourcontrola o estado atual (a vida caindo).
Passo 3: A Mágica Acontecendo (Criando os Assets)
Volte para a Unity.
- Na sua pasta de Assets, crie uma pasta (ex: “Stats”).
- Dentro dela, clique com o botão direito: Create > PERAI DEV > Stats Personagem.
- Renomeie esse novo asset para “Stats_Goblin”.
- Selecione o asset “Stats_Goblin” e veja o Inspector. Mude a
Vida Maximapara 50. - Repita o processo. Crie outro asset chamado “Stats_Ogro”. Mude a
Vida Maximadele para 200 e aVelocidade Movimentopara 2.
Você acabou de criar duas “peças de Lego” de atributos, sem escrever uma linha de código a mais.
Passo 4: Montando o “Lego”
Agora, vamos usar isso.
- Crie um GameObject na sua cena. Pode ser um simples Capsule. Chame-o de “Goblin”.
- Adicione o script
SistemaDeVidano “Goblin”. - Veja o campo
Stats Baseno Inspector. Ele está vazio (“None”). - Arraste o seu asset “Stats_Goblin” (lá da pasta “Stats”) para dentro desse campo
Stats Base. - Crie outro GameObject, chame-o de “Ogro”.
- Adicione o script
SistemaDeVidanele. - Arraste o seu asset “Stats_Ogro” para dentro do campo
Stats Basedele.
Pronto.
Agora dê Play.
Selecione o “Goblin”. No Inspector do SistemaDeVida, clique com o botão direito no nome do script e selecione “Testar: Tomar 10 de Dano”. Você verá no console que ele morre quando a vida (que começou em 50) chega a zero.
Faça o mesmo com o “Ogro”. Ele vai aguentar muito mais porrada, pois a vida dele começou em 200.
Ambos estão usando o exato mesmo script SistemaDeVida. A única diferença é a “peça de Lego” de stats que você encaixou.
Conclusão: O Poder do “Molde”
Percebeu?
Agora, se você decidir que todos os Goblins do seu jogo precisam ter 60 de vida, adivinha? Você não precisa caçar os 300 prefabs de Goblin.
Você só precisa abrir o asset “Stats_Goblin” e mudar o valor de 50 para 60.
Automaticamente, todos os inimigos, prefabs e objetos na cena que usam aquele “molde” serão atualizados.
Isso é trabalhar de forma inteligente. Você separou seus dados da sua lógica. Você pode ter um único script SistemaDeVida para o jogador, para o NPC, para o inimigo fraco e para o chefe final. O que muda é apenas o “molde” de ScriptableObject que você encaixa nele.
Agora, tente expandir. Adicione danoAtaque no StatsPersonagemSO e crie um script de Ataque.cs que lê esse valor. As possibilidades são infinitas.





