Componentes
Um componente é uma classe C# anexada a um nó. Os nós guardam onde algo está; os componentes decidem o que é e como se comporta.
Declarando um componente
Herde de Component e dê à classe um construtor público sem parâmetros (o padrão serve):
namespace Usercode;
public class Health : Component
{
public int maximum = 100;
public int Current { get; private set; }
public override void OnStart() => Current = maximum;
public void Damage(int amount)
{
Current = Math.Max(0, Current - amount);
if (Current == 0) Node!.IsActive = false;
}
}
Todo componente que você declara aparece no menu Add Component do Inspector. Agrupe-o sob um caminho com [ComponentContextMenu("Gameplay/Health")].
O tipo de um componente é identificado nos arquivos de cena por um id estável. Para os seus scripts, ele vem do arquivo .cs.meta do script, criado automaticamente na primeira compilação; os tipos do motor o declaram com [TypeId("…")]. De qualquer forma, renomear a classe ou mudá-la de namespace não quebra as cenas salvas.
Ciclo de vida
| Callback | Quando |
|---|---|
OnAttached() |
Logo após o componente ser anexado a um nó. |
OnAwake() |
Uma vez, no primeiro anexo — mesmo inativo. Resolva serviços aqui. |
OnEnable() |
O componente fica ativo; também logo após OnAwake quando começa ativo. |
OnStart() |
Uma vez, no primeiro quadro em que o componente está ativo, antes da primeira atualização. |
OnFixedUpdate(float fixedDeltaTime) |
Em passos fixos de 60 Hz, tantas vezes quanto o tempo decorrido exigir. |
OnUpdate(float deltaTime) |
Uma vez por quadro. |
OnLateUpdate(float deltaTime) |
Uma vez por quadro, depois de todos os OnUpdate — para câmeras que seguem objetos em movimento. |
OnDisable() |
O componente ou seu nó fica inativo. |
OnDetached() |
Logo antes de o componente sair do nó. |
OnDestroy() |
O componente é removido ou seu nó é destruído. |
A cada quadro, o motor primeiro inicia os componentes que ainda não começaram, depois executa os passos fixos, depois OnUpdate na árvore inteira e então OnLateUpdate. Nós e componentes inativos são ignorados. Uma exceção lançada por um componente é registrada com o nome do componente e não interrompe o jogo.
Ativação
component.IsActive liga ou desliga um componente. node.IsActive liga ou desliga um nó: seus componentes recebem OnEnable/OnDisable, e enquanto ele está inativo o motor ignora o nó e todos os seus descendentes.
Conversando com outros componentes
var health = Node!.GetComponent<Health>(); // no mesmo nó, ou null
var all = Node.GetComponents<LightComponent>(); // todos os do nó
var inChildren = Node.GetComponentsInChildren<Health>(); // o nó e seus descendentes
bool hasCamera = Node.HasComponent<CameraComponent>();
var light = Node.AddComponent<LightComponent>(); // anexar em tempo de execução
Node.RemoveComponent(light);
Para apontar para um componente em outro nó, exponha um campo ComponentRef<T> e arraste o nó para ele no Inspector; chame Resolve(raizDaCena) em tempo de execução. NodeRef<Node> faz o mesmo para nós.
Serviços do motor
Os scripts acessam os serviços do motor por RuntimeServices, que funciona igual no Play Mode e nos jogos exportados:
ISceneManager? scenes;
public override void OnAwake() => scenes = RuntimeServices.TryGet<ISceneManager>();
Serviços disponíveis para scripts: ISceneManager (cenas), IAssetLoader (assets), IInputSource e InputActionService (entrada) e LocaleService (localização). As fachadas estáticas Input, InputActions e Localization cobrem as chamadas mais comuns.
Atributos
| Atributo | Em | Efeito |
|---|---|---|
[ComponentContextMenu("Caminho/Nome")] |
classe | Posiciona o componente no menu Add Component. |
[DisallowMultipleComponent] |
classe | No máximo um por nó. |
[RequireComponent(typeof(T))] |
classe | Adicionar este componente também adiciona T. |
[HideInEditor] |
membro | Oculta um membro público do Inspector. |
[ShowInEditor] |
membro | Mostra um membro não público. |
[ReadOnly] |
membro | Mostra o valor sem permitir edição. |
[Range(min, max)] |
número | Limita a edição ao intervalo. |
[NumericUpDown] |
número | Desenha um campo com setas. |
[Button] |
método | Desenha um botão que chama o método sem parâmetros. |
[Expand(false)] |
membro | Começa um grupo recolhido. |
[EnumLabel("…")] |
valor de enum | Substitui o rótulo nas listas. |
Logging
Log.Logger é um ILogger padrão de Microsoft.Extensions.Logging:
Log.Logger.LogInformation("Pegou {Item}", item.Name);
Log.Logger.LogWarning("Vida baixa: {Current}", Current);
As mensagens aparecem no painel Output do Studio e no console de um jogo em execução.
Componentes embutidos
| Componente | Menu | Finalidade |
|---|---|---|
CameraComponent |
Rendering/Camera | Visão em perspectiva ou ortográfica. A câmera ativa de maior Priority renderiza. |
FreeFlyCameraComponent |
Rendering/Camera/Free Fly | Câmera voadora com WASD + mouse. |
FpsCameraComponent |
Rendering/Camera/FPS | Olhar e movimento em primeira pessoa. |
OrbitCameraComponent |
Rendering/Camera/Orbit | Orbita um ponto; role a roda para aproximar. |
FollowCameraComponent |
Rendering/Camera/Follow | Segue um nó a uma distância. |
LightComponent |
Rendering/Light | Luz pontual ou direcional. |
ModelComponent |
Rendering/Model | Desenha um modelo importado, com materiais substituíveis por submalha. |
MeshComponent |
Rendering/Mesh | Desenha uma única malha. |
UiDocumentComponent |
UI/UI Document | Renderiza um documento .ui na tela ou no mundo. Veja Interface do jogo. |
UiRaycasterComponent |
UI/UI Raycaster | Torna clicável um documento de interface no mundo. |