Add manual radar ping, blip refresh/fade, and resolution statue barrier
- Manual hider ping on "E": server-authoritative RequestManualPing gated to Seek + living hider; shared EmitRadarPings path so interval and manual pings produce identical blips. Ping key read client-side in GameModeManager, role- gated and excluded in FreeCam (E is fly-up there). - Radar refreshes an existing blip for the same transform target instead of duplicating it (lifetime resets to the configured value) via RadarTarget.Refresh. - Blips fade in/out independently of the disc fade: per-blip MoveTowards factor multiplied on top of the radar fade, refresh-safe, with separate in/out speeds. - Resolution countdown waits for conversion statues to load: generalized the match-start loading barrier (RunReadinessBarrier over _barrierTargets, hold phase carried in MsgBeginLoad) and run it a second time over statue IDs before starting the real resolveDuration. Only holds for Conversion with real statues. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
8f31c07bef
commit
bfcd84afe4
4 files changed
+199
-64
No files matched your search
@@ -117,6 +117,18 @@ public sealed class Radar : MonoBehaviour
|
||||
return null;
|
||||
}
|
||||
|
||||
// Already tracking this exact transform? Refresh its countdown instead of stacking a duplicate blip,
|
||||
// so a fresh ping (interval or manual) just resets the existing target's lifetime.
|
||||
for (int i = 0; i < _blips.Count; i++)
|
||||
{
|
||||
var existing = _blips[i];
|
||||
if (existing && existing.Target == target)
|
||||
{
|
||||
existing.Refresh(lifetime);
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
|
||||
Transform clone = Instantiate(targetTemplate, targetTemplate.parent);
|
||||
clone.name = "Target";
|
||||
clone.localPosition = targetTemplate.localPosition;
|
||||
|
||||
@@ -7,6 +7,11 @@ using UnityEngine;
|
||||
/// 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.
|
||||
///
|
||||
/// On top of the radar-wide fade, each blip fades in when it spawns and fades out at the end of its life (or when
|
||||
/// its world target vanishes) via its own <see cref="_fade"/> factor, so blips appear/disappear smoothly instead
|
||||
/// of popping. Fade-in and fade-out speeds are independent; the factor persists across <see cref="Refresh"/> so a
|
||||
/// refreshed blip is pulled back to full opacity rather than flickering to zero first.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class RadarTarget : MonoBehaviour
|
||||
@@ -20,11 +25,18 @@ public sealed class RadarTarget : MonoBehaviour
|
||||
[Tooltip("camera -> target distance mapped onto pointDistanceScale: x = near distance, y = far distance.")]
|
||||
[SerializeField] Vector2 pointDistanceRange;
|
||||
|
||||
[Header("Fade")]
|
||||
[Tooltip("Per-blip fade-in speed in alpha units per second when the blip appears. e.g. 6 = ~0.17s. 0 = appear instantly.")]
|
||||
[SerializeField] float fadeInSpeed = 6f;
|
||||
[Tooltip("Per-blip fade-out speed in alpha units per second at the end of life / when the target vanishes. e.g. 4 = ~0.25s. 0 = vanish instantly.")]
|
||||
[SerializeField] float fadeOutSpeed = 4f;
|
||||
|
||||
private Transform _target;
|
||||
private Camera _camera;
|
||||
private float _lifetime;
|
||||
private float _age;
|
||||
private bool _initialised;
|
||||
private float _fade; // per-blip 0..1 ramp, multiplied on top of the radar-wide fade; persists across Refresh
|
||||
|
||||
private MaterialPropertyBlock _mpb;
|
||||
private Color _pointColor = Color.white; // last gradient-evaluated point colour; its alpha is scaled by the radar fade
|
||||
@@ -44,27 +56,39 @@ public sealed class RadarTarget : MonoBehaviour
|
||||
PushPointColor();
|
||||
}
|
||||
|
||||
/// <summary>Restarts this blip's countdown to <paramref name="lifetime"/> seconds. Used when a ping arrives
|
||||
/// for a target this radar already tracks: the existing blip is refreshed instead of stacking a duplicate.</summary>
|
||||
public void Refresh(float lifetime)
|
||||
{
|
||||
_lifetime = lifetime;
|
||||
_age = 0f;
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
// Fade out at the very end of life, or immediately if the world target vanished (e.g. a caught hider)
|
||||
// instead of dangling. The fade-out window equals the time to ramp 1 -> 0 at fadeOutSpeed, so the point
|
||||
// reaches full transparency right as the lifetime elapses; then the blip destroys itself.
|
||||
float fadeOutWindow = fadeOutSpeed > 0f ? 1f / fadeOutSpeed : 0f;
|
||||
bool fadingOut = !_target || RemainingLifetime <= fadeOutWindow;
|
||||
|
||||
float goal = fadingOut ? 0f : 1f;
|
||||
float speed = Mathf.Max(0f, fadingOut ? fadeOutSpeed : fadeInSpeed);
|
||||
_fade = Mathf.MoveTowards(_fade, goal, speed * Time.deltaTime);
|
||||
|
||||
if (fadingOut && (speed <= 0f || _fade <= 0.0001f))
|
||||
{
|
||||
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
|
||||
Aim(); // keeps last orientation/colour if the target is gone (Aim early-returns)
|
||||
PushPointColor(); // every frame so the alpha tracks both the radar fade and this blip's own fade
|
||||
}
|
||||
|
||||
private void Aim()
|
||||
@@ -100,13 +124,13 @@ public sealed class RadarTarget : MonoBehaviour
|
||||
_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.
|
||||
// Writes the point's _BaseColor with its alpha scaled by both the radar's shared fade factor (so blips fade in
|
||||
// step with the disc) and this blip's own fade (so it eases in on spawn and out at the end of its life).
|
||||
private void PushPointColor()
|
||||
{
|
||||
if (!pointRenderer) return;
|
||||
Color c = _pointColor;
|
||||
c.a *= Radar.Instance ? Radar.Instance.CurrentFade : 1f;
|
||||
c.a *= (Radar.Instance ? Radar.Instance.CurrentFade : 1f) * _fade;
|
||||
_mpb ??= new MaterialPropertyBlock();
|
||||
pointRenderer.GetPropertyBlock(_mpb);
|
||||
_mpb.SetColor(BaseColorId, c);
|
||||
|
||||
Reference in new issue
Block a user