Programando seu jogo
Seu primeiro componente
Crie um arquivo .cs em qualquer lugar da pasta Assets/ do projeto — por exemplo Assets/Scripts/Rotator.cs:
namespace Usercode;
public class Rotator : Component
{
/// <summary>Graus por segundo.</summary>
public float speed = 90f;
public override void OnUpdate(float deltaTime) =>
Node!.Transform.SetRotationY(Node.Transform.Rotation.Y + speed * deltaTime);
}
Salve o arquivo. O Studio percebe a mudança, recompila os scripts em segundo plano e troca o assembly — erros de compilação aparecem no painel Output. Depois selecione um nó, clique em Add Component no Inspector e escolha Rotator, ou arraste o script do painel Assets sobre o nó.
Na primeira vez que o Studio compila um script, ele grava um Rotator.cs.meta ao lado. Esse arquivo guarda o id que as cenas usam para encontrar o componente; mantenha-o junto do script e versione-o também.
Boas práticas:
- Uma classe de componente por arquivo, com o mesmo nome do arquivo.
- Scripts são C# comum no .NET 10: use qualquer recurso da linguagem e a biblioteca de classes base.
- Projetos novos incluem
Assets/Globals.cs, cujas linhasglobal usingtrazem o motor (Turian.Engine.Core,Turian.Engine.UI), seus atributos (Turian),System.Numerics, logging e os códigos de teclas para todos os scripts. Edite à vontade. - Use
Log.Logger(um logger deMicrosoft.Extensions.Logging) para escrever no painel Output e no console.
Callbacks de ciclo de vida
Sobrescreva apenas os que precisar:
| Callback | Quando é chamado |
|---|---|
OnAwake() |
Uma vez, quando o componente é anexado pela primeira vez — mesmo inativo. |
OnEnable() |
O componente fica ativo (também logo após OnAwake, se ativo). |
OnStart() |
Uma vez, no primeiro quadro, antes do primeiro OnUpdate. |
OnUpdate(float deltaTime) |
A cada quadro enquanto ativo; deltaTime em segundos. |
OnLateUpdate(float deltaTime) |
A cada quadro, depois de todos os OnUpdate. |
OnFixedUpdate(float fixedDeltaTime) |
Em um passo de tempo fixo. |
OnDisable() |
O componente fica inativo. |
OnDestroy() |
O componente é removido ou seu nó é destruído. |
Veja Componentes para o modelo completo.
Exemplo: contador de FPS
public class FpsCounter : Component
{
float elapsed;
int frames;
public override void OnUpdate(float deltaTime)
{
elapsed += deltaTime;
frames++;
if (elapsed < 1f) return;
Log.Logger.LogInformation("FPS: {Fps:F1}", frames / elapsed);
elapsed = 0f;
frames = 0;
}
}
Editando valores no Inspector
Campos públicos e propriedades com setter viram controles no Inspector, salvos por nó na cena:
| Tipo | Controle no Inspector |
|---|---|
bool |
caixa de seleção |
inteiros, float, double, decimal |
campo numérico — arraste o rótulo para ajustar |
string |
campo de texto |
| enums | lista suspensa |
Vector2, Vector3, Vector4 |
um campo por eixo |
List<T> |
lista redimensionável |
| classes e structs aninhadas | grupo recolhível |
AssetReference<T> |
slot de asset — solte um asset do painel Assets |
NodeRef<Node>, ComponentRef<T> |
slot de cena — solte um nó da Scene Tree |
Atributos ajustam como um membro aparece:
public class Patrol : Component
{
[Range(0, 20)] public float speed = 2.5f; // edição limitada ao intervalo
public ComponentRef<CameraComponent>? watcher; // solte um nó com câmera aqui
public AssetReference<Prefab>? loot; // solte um .prefab aqui
[ReadOnly] public int visits; // visível, não editável
[Hide] public float internalTimer; // público, mas oculto
[Button] // desenhado como botão no Inspector
public void ResetVisits() => visits = 0;
}
Campos privados ficam ocultos, a menos que marcados com [Show]. Um campo de referência de cena guarda o id do nó alvo; chame Resolve(raiz) para obter o objeto vivo:
var root = Node!;
while (root.Parent is not null) root = root.Parent;
var camera = watcher?.Resolve(root);
Próximos passos
- Entrada — teclado, mouse, gamepad e mapas de ações.
- Cenas — carregar e trocar de cena.
- Interface do jogo — menus e HUDs com documentos
.ui.