Pular para o conteúdo
AstraDOCS

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.

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.

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.

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.

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.

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.