Planets, belts, wells, loot, mines, stations, the chunk reticle and the flow clock are evaluated through DrawAhead (Time, Orbit, Height, Position) at one drawn time; the rail law lives once in Zone.Offset; OrbitPositionAt, GetHeight, ChunkPose, EvaluateBelt and RideHeight take a time. Fixes the planet jumping against a co-moving ship at display rates above the step rate. Not yet built or run (Unity presenter files are verified by compile only on Starfire). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
75 lines
2.7 KiB
C#
75 lines
2.7 KiB
C#
using CultMath;
|
|
using CultMath.UnityBridge;
|
|
using UnityEngine;
|
|
using static CultMath.math;
|
|
using Random = UnityEngine.Random;
|
|
|
|
// How one laid mine looks. Zone owns the mine's every fact (position, arming, trigger, end); this reads them and
|
|
// draws, and writes nothing back. The pose is the latest sim body, spun for show; the pulse runs in real time
|
|
// (rulings unity-presents-only-r3 and sim-speed-presentation).
|
|
public class MineInstance : MonoBehaviour
|
|
{
|
|
public MeshRenderer MeshRenderer;
|
|
public int EmissionSubmesh = 2;
|
|
public AnimationCurve EmissionCurve;
|
|
public float ActiveCycleDuration = 1f;
|
|
public float ArmedCycleDuration = .25f;
|
|
public float ActiveEmission = 100f;
|
|
public float ArmedEmission = 1000f;
|
|
public float RotationSpeed = 1f;
|
|
public float GridOffset;
|
|
// The blast's particles; the effect prefab destroys itself when its particle system stops.
|
|
public GameObject HitEffect;
|
|
public float HitEffectScale = 10f;
|
|
|
|
private Zone _zone;
|
|
private Mine _mine;
|
|
private Material _material;
|
|
private float _timeOffset;
|
|
private float _pulse;
|
|
private float _emission;
|
|
|
|
public void Bind(Zone zone, Mine mine)
|
|
{
|
|
_zone = zone;
|
|
_mine = mine;
|
|
_material = MeshRenderer.materials[EmissionSubmesh];
|
|
_timeOffset = Random.value * 100;
|
|
Place();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
Place();
|
|
transform.localRotation = Quaternion.Euler(
|
|
sin(Time.time - _timeOffset * RotationSpeed) * 90, 0, cos(Time.time - _timeOffset * RotationSpeed) * 90);
|
|
|
|
// None before the mine arms, then slow while it waits and fast once its fuse is lit.
|
|
var armed = _mine.Armed(_zone.Time);
|
|
var counting = _mine.TriggeredAt != null;
|
|
var target = !armed ? 0f : counting ? ArmedEmission : ActiveEmission;
|
|
_emission = lerp(_emission, target, Time.deltaTime * 10);
|
|
_pulse = (_pulse + Time.deltaTime / (counting ? ArmedCycleDuration : ActiveCycleDuration)) % 1;
|
|
_material.SetFloat("_Emission", _emission * EmissionCurve.Evaluate(_pulse));
|
|
}
|
|
|
|
private void Place()
|
|
{
|
|
var lead = ActionGameManager.Clock.Lead;
|
|
var p = DrawAhead.Position(_mine.Body, lead);
|
|
transform.position = new Vector3(p.x, DrawAhead.Height(_zone, p, lead) + GridOffset, p.y);
|
|
}
|
|
|
|
// The mine left Zone.Mines, which only its blast does: show it where it was drawn last.
|
|
public void Blast()
|
|
{
|
|
var effect = Instantiate(HitEffect, transform.position, Quaternion.identity);
|
|
effect.transform.localScale = Vector3.one * HitEffectScale;
|
|
Destroy(gameObject);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_material) Destroy(_material);
|
|
}
|
|
}
|