Files
chameleon/Assets/Scripts/Components/RadarTarget.cs
T
adminandClaude Opus 4.8 cad5015d42 Radar: fade in/out statt hartem Enable-Toggle
Gemeinsamer 0..1-Fade-Faktor treibt Disc-Alpha (baseAlpha * fade via MPB),
Blip-Alpha (RadarTarget, im Gleichschritt) und Radar-Scale (0.8 -> 1.0).
Fade-in/-out-Speed separat einstellbar; Kamera bleibt an solange fade > 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 12:23:42 +02:00

116 lines
4.7 KiB
C#

using UnityEngine;
/// <summary>
/// A single radar blip spawned by <see cref="Radar"/>. Each frame it orients itself so its forward (+Z, where
/// the "Point" marker sits) faces the direction from the reference camera to a world-space target, visualising
/// the bearing camera -> target. Tracks continuously (the camera turns / the target moves) and self-destructs
/// once its lifetime elapses - or earlier if its target is destroyed. The point's base colour and size encode
/// the two things the flat radar disc can't show via position alone: <see cref="forwardGradient"/> tints it by
/// how far the target sits ahead of / behind the camera, and its scale shrinks with camera -> target distance.
/// </summary>
[DisallowMultipleComponent]
public sealed class RadarTarget : MonoBehaviour
{
public Renderer pointRenderer;
[Tooltip("Point tint by bearing: sampled at 0 when the target is dead ahead of the camera, at 1 when directly behind. Flip the keys for the reverse.")]
[SerializeField] Gradient forwardGradient;
[Tooltip("Point transform scale at the near (x) and far (y) end of pointDistanceRange.")]
[SerializeField] Vector2 pointDistanceScale;
[Tooltip("camera -> target distance mapped onto pointDistanceScale: x = near distance, y = far distance.")]
[SerializeField] Vector2 pointDistanceRange;
private Transform _target;
private Camera _camera;
private float _lifetime;
private float _age;
private bool _initialised;
private MaterialPropertyBlock _mpb;
private Color _pointColor = Color.white; // last gradient-evaluated point colour; its alpha is scaled by the radar fade
private static readonly int BaseColorId = Shader.PropertyToID("_BaseColor");
public Transform Target => _target;
public float RemainingLifetime => Mathf.Max(0f, _lifetime - _age);
public void Init(Transform target, Camera referenceCamera, float lifetime)
{
_target = target;
_camera = referenceCamera;
_lifetime = lifetime;
_age = 0f;
_initialised = true;
Aim();
PushPointColor();
}
// LateUpdate so the aim uses the camera's final position/rotation for this frame.
private void LateUpdate()
{
if (!_initialised) return;
_age += Time.deltaTime;
if (_age >= _lifetime)
{
Destroy(gameObject);
return;
}
// The world target may despawn (e.g. a caught hider) before this blip expires - drop it, don't dangle.
if (!_target)
{
Destroy(gameObject);
return;
}
Aim();
PushPointColor(); // every frame so the blip's alpha tracks the radar fade even when Aim early-returns
}
private void Aim()
{
if (!_target || !_camera) return;
Vector3 dir = _target.position - _camera.transform.position;
float sqr = dir.sqrMagnitude;
if (sqr < 1e-8f) return; // camera sitting on the target -> keep the last orientation/colour/scale
transform.rotation = Quaternion.LookRotation(dir);
float distance = Mathf.Sqrt(sqr);
ApplyDistanceScale(distance);
ApplyForwardColor(dir / distance);
}
// Shrinks the blip with distance: pointDistanceRange (near, far) remapped onto pointDistanceScale (near, far), clamped.
private void ApplyDistanceScale(float distance)
{
if (!pointRenderer) return;
float t = Mathf.InverseLerp(pointDistanceRange.x, pointDistanceRange.y, distance);
float s = Mathf.Lerp(pointDistanceScale.x, pointDistanceScale.y, t);
pointRenderer.transform.localScale = new Vector3(s, s, s);
}
// Tints the point's base colour by how far the target sits ahead of (0) vs directly behind (1) the camera.
// Only caches the colour here; PushPointColor writes it (with the fade applied) so the alpha can track the
// radar fade every frame independent of when the bearing last changed.
private void ApplyForwardColor(Vector3 dirNormalized)
{
if (forwardGradient == null) return;
float t = Vector3.Angle(_camera.transform.forward, dirNormalized) / 180f;
_pointColor = forwardGradient.Evaluate(t);
}
// Writes the point's _BaseColor with its alpha scaled by the radar's shared fade factor, so blips fade in/out
// in step with the disc instead of the overlay snapping on/off.
private void PushPointColor()
{
if (!pointRenderer) return;
Color c = _pointColor;
c.a *= Radar.Instance ? Radar.Instance.CurrentFade : 1f;
_mpb ??= new MaterialPropertyBlock();
pointRenderer.GetPropertyBlock(_mpb);
_mpb.SetColor(BaseColorId, c);
pointRenderer.SetPropertyBlock(_mpb);
}
}