Classes Serializáveis
Parte da seção Arquitetura de Jogos no Unity do Journey de Unity da Coddy. Lição 18 de 64.
Um script com muitas configurações fica com uma lista longa e plana no Inspector. Uma classe C# simples pode agrupá-las: marque-a com [System.Serializable], e um campo dessa classe será exibido como uma seção recolhível com o nome do campo, contendo os campos da classe. Uma classe pode ser usada por vários campos e vários scripts:
[System.Serializable]
public class Stats
{
public float speed = 2f;
public int damage = 10;
}
public class Enemy : MonoBehaviour
{
public Stats normal;
public Stats enraged;
private Stats current;
void Start()
{
current = normal;
}
void Update()
{
transform.Translate(0f, 0f, current.speed * Time.deltaTime);
}
public void Enrage()
{
current = enraged;
}
}O Inspector mostra duas seções recolhíveis, Normal e Enraged, cada uma com Speed e Damage. Cada Enemy recebe seus próprios dois objetos Stats, preenchidos no próprio Inspector, e o código os acessa como normal.speed. O Unity cria esses objetos quando carrega o script, então normal nunca é null, mesmo sem = new Stats(), e os inicializadores de campo (2 e 10) são os valores iniciais de um novo Enemy. Uma struct funciona da mesma maneira com o atributo, [System.Serializable] public struct Range { public float min; public float max; }, e, assim como Vector3, ela é copiada quando é atribuída.
O atributo é necessário porque o Unity salva apenas os tipos que recebe instruções para salvar. Sem ele, a classe fica invisível no Inspector: não há seção recolhível, os valores definidos ali não são salvos e o Unity não cria o objeto, então normal.speed gera uma NullReferenceException. Dentro da classe, valem as regras habituais do Inspector: campos públicos ou campos privados com [SerializeField], nunca propriedades ou campos estáticos.
Desafio
FácilAgrupe as configurações de cada feixe em uma struct.
- Acima de
Flashlight, declarepublic struct BeamcomColor color,float rangeefloat anglepúblicos. Marque-a como[System.Serializable]para que ela apareça no Inspector. - Substitua os seis campos separados por
public Beam wide;epublic Beam focused;. - Em
Apply(), defina os três valores da luz usandofocusedOn ? focused : wide.
Pressione “Jogar” e a tecla Espaço: o feixe alcança o cristal. Em seguida, pressione “Verificar”.
Experimente você mesmo
using UnityEngine;
using UnityEngine.InputSystem;
public class Flashlight : MonoBehaviour
{
public Color wideColor = Color.white;
public float wideRange = 5f;
public float wideAngle = 60f;
public Color focusedColor = Color.white;
public float focusedRange = 10f;
public float focusedAngle = 30f;
private bool focusedOn;
private Light lamp;
void Start()
{
lamp = GetComponent<Light>();
Apply();
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
focusedOn = !focusedOn;
Apply();
}
}
void Apply()
{
lamp.color = focusedOn ? focusedColor : wideColor;
lamp.range = focusedOn ? focusedRange : wideRange;
lamp.spotAngle = focusedOn ? focusedAngle : wideAngle;
}
}
Todas as lições de Arquitetura de Jogos no Unity
1Componentes, não hierarquias
Componentes pequenosUm script base de inimigoComponentes abstratosComponentes trabalhando juntosRevisão: torre modularRevisão: canhão duplo4Dados Serializados
Classes SerializáveisListas no InspectorEnums no InspectorRevisão: Tabela de LootRevisão: Sorteie o Loot2Interfaces no Unity
IDamageableInterfaces e TryGetComponentGetComponentsRevisão: tecla de interaçãoRevisão: mais próximo ao alcance5ScriptableObjects
Ativos de DadosAtributos da ArmaConfigurações CompartilhadasSalve o VentoOndas como DadosRevisão: Banco de ItensRevisão: Comprar na LojaPratique por conta própria: Playground de Unity