Exemplos da API gráfica
Seis receitas que rodaram no celular, cada uma em C# e em Flow: dia acelerado, perfil por área, desfoque ao mirar, postes ao anoitecer, sonda por script e troca de material.
Validado no aparelho · APK 0.4.0 · os seis, em C# e em Flow, no POCO F7 em 26/10
Monte cada um numa cena sua: os nomes de objeto (Sol, Postes, Volume global) são os do exemplo; escolha os seus nos campos do Inspector do script ou do cartão da Conexão de evento.
O exemplo 3, desfoque ao mirar, está completo em API gráfica com os nomes da Unity e em Entrada do jogador.
1. Ciclo de dia acelerado
Seção intitulada “1. Ciclo de dia acelerado”No objeto do Sol (Luz direcional + Hora do dia). Um dia inteiro em 2 minutos; a sonda de reflexo (Tempo real, Por script) é recapturada a cada 15 minutos de jogo para o chão não refletir o céu da tarde a noite inteira.
using Astra;using Astra.Components;
[ComponentId("g7.dia_acelerado")]public sealed class DiaAcelerado : Behavior{ [PropertyId("velocidade")] public float Velocidade = 720; [PropertyId("hora_inicial")] public float HoraInicial = 16; [PropertyId("sonda")] public ObjectReference Sonda;
private TimeOfDay tempo; private int quartoDeHora = -1;
public override void Start() { tempo = Object.GetComponent<TimeOfDay>()!.Value; tempo.Hour = HoraInicial; // TimeOfDay.Current.Hour = 16 tempo.Speed = Velocidade; // 1 min real = 12 h de jogo tempo.HourChanged(this, hora => Scene.Log(ObjectId, $"Hora do dia: {hora:00}:00")); tempo.Sunset(this, () => Scene.Log(ObjectId, "Pôr do sol")); tempo.Sunrise(this, () => Scene.Log(ObjectId, "Nascer do sol")); }
public override void Update(float deltaTime) { var quarto = (int)(tempo.Hour * 4); if (quarto == quartoDeHora) return; quartoDeHora = quarto; if (Resolve(Sonda)?.GetComponent<ReflectionProbe>() is { } sonda) sonda.RenderProbe(); }}Em Flow, sem código: No Sol: Duração do dia 2 min. Conexão de evento: Hora do dia: hora mudou → Chamar método Sonda de reflexo: capturar agora, Receptor = a sonda.
2. Perfil de Volume ao entrar numa área
Seção intitulada “2. Perfil de Volume ao entrar numa área”No sensor da área (Corpo físico sensor + Colisor). Quem entra troca o perfil compartilhado do Volume global; quem sai devolve o de antes.
using Astra;using Astra.Rendering;
[ComponentId("g7.perfil_por_area")]public sealed class PerfilPorArea : Behavior{ [PropertyId("volume")] public ObjectReference VolumeGlobal; [PropertyId("perfil_da_area")] public AssetReference PerfilDaArea;
private Volume? volume; private AssetGuid perfilDeFora;
public override void Start() { volume = Volume.Get(Resolve(VolumeGlobal)!); perfilDeFora = volume!.SharedProfile; }
public override void TriggerEnter(ObjectReference other) { volume!.SharedProfile = AssetGuid.Parse(PerfilDaArea.AssetId); Scene.Log(ObjectId, "Perfil da área ativo"); }
public override void TriggerExit(ObjectReference other) => volume!.SharedProfile = perfilDeFora;}Em Flow, sem código: No sensor: Sensor 3D: entrou → Volume: trocar perfil, Perfil = Área coberta, Receptor = o Volume global; Sensor 3D: saiu → Volume: trocar perfil, Perfil = Exterior.
4. Postes que acendem ao anoitecer
Seção intitulada “4. Postes que acendem ao anoitecer”No Sol. No pôr do sol liga a Luz de cada poste e acende a lâmpada pela cor de emissão (_EmissionColor); no nascer apaga.
using Astra;using Astra.Components;
[ComponentId("g7.postes_ao_anoitecer")]public sealed class PostesAoAnoitecer : Behavior{ [PropertyId("postes")] public ObjectReference Postes; [PropertyId("velocidade")] public float Velocidade = 720; [PropertyId("hora_inicial")] public float HoraInicial = 17.2f;
public override void Start() { var tempo = Object.GetComponent<TimeOfDay>()!.Value; tempo.Hour = HoraInicial; tempo.Speed = Velocidade; tempo.Sunset(this, () => Acender(true)); tempo.Sunrise(this, () => Acender(false)); Acender(false); }
private void Acender(bool aceso) { foreach (var poste in Resolve(Postes)!.Children()) foreach (var parte in poste.Children()) { if (parte.GetComponent<Light>() is { } luz) luz.Enabled = aceso; if (parte.GetComponent<MeshRenderer>() is { } lampada) lampada.Material.SetColor("_EmissionColor", aceso ? new Color(4f, 2.6f, 1.2f) : new Color(0, 0, 0)); } Scene.Log(ObjectId, aceso ? "Postes acesos" : "Postes apagados"); }}Em Flow, sem código: No Sol: Hora do dia: pôr do sol → Ativar objeto = Postes; Hora do dia: nascer do sol → Desativar objeto = Postes.
5. Recapturar uma sonda por script
Seção intitulada “5. Recapturar uma sonda por script”Na Sonda de reflexo (Tempo real, Por script). A cada intervalo troca a cor de um painel e recaptura: o reflexo só muda quando o script pede.
using Astra;using Astra.Components;
[ComponentId("g7.sonda_por_script")]public sealed class SondaPorScript : Behavior{ [PropertyId("painel")] public ObjectReference Painel; [PropertyId("intervalo")] public float Intervalo = 2;
private static readonly Color[] Cores = [new(1, .1f, .05f), new(.05f, .8f, .2f), new(.1f, .3f, 1)]; private float relogio; private int cor;
public override void Start() { var sonda = Object.GetComponent<ReflectionProbe>()!.Value; sonda.Mode = ReflectionProbeMode.Realtime; sonda.RefreshModeUnity = ReflectionProbeRefreshMode.ViaScripting; Pintar(); }
public override void Update(float deltaTime) { relogio += deltaTime; if (relogio < Intervalo) return; relogio = 0; cor = (cor + 1) % Cores.Length; Pintar(); }
private void Pintar() { var painel = Resolve(Painel)!.GetComponent<MeshRenderer>()!.Value; painel.Material.SetColor("_BaseColor", Cores[cor]); painel.Material.SetColor("_EmissionColor", Cores[cor] * 3); Object.GetComponent<ReflectionProbe>()!.Value.RenderProbe(); Scene.Log(ObjectId, "Sonda recapturada"); }}Em Flow, sem código: Num Timer de 2 s: Timer disparou → Sonda de reflexo: capturar agora, Receptor = a sonda.
6. Trocar o material
Seção intitulada “6. Trocar o material”No objeto com Mesh Renderer. Alterna entre um material Lit (ouro) e um Unlit (neon) e, no Lit, ajusta a suavidade pelo nome da URP.
using Astra;using Astra.Components;
[ComponentId("g7.troca_de_material")]public sealed class TrocaDeMaterial : Behavior{ [PropertyId("material_a")] public AssetReference MaterialA; [PropertyId("material_b")] public AssetReference MaterialB; [PropertyId("intervalo")] public float Intervalo = 2;
private float relogio; private bool usandoB;
public override void Update(float deltaTime) { relogio += deltaTime; if (relogio < Intervalo) return; relogio = 0; usandoB = !usandoB; var malha = Object.GetComponent<MeshRenderer>()!.Value; malha.SharedMaterial = AssetGuid.Parse((usandoB ? MaterialB : MaterialA).AssetId); if (!usandoB) malha.Material.SetFloat("_Smoothness", .9f); Scene.Log(ObjectId, usandoB ? "Material B (Unlit)" : "Material A (Lit)"); }}Em Flow, sem código: Num Timer: Timer disparou → Malha: trocar material, Material = Neon; outro Timer volta ao Ouro.