Hunter shot: replicated laser beam + X-ray hit flash; snapshot apply in-place reseed
- Laser.shader + HunterLaserBeam: additive HDR beam, fade in/out over opacity and thickness, code-driven LineRenderer, tunable emission multiplier. - FirstPersonMode: TryShoot computes world endpoint, fires beam with lateral muzzle offset (right) so it isn't dead-center from hunter view. - NetworkPlayerSetup: shot relay RPCs (owner->server->all) + hit-flash RPC (server->all), flash OR-branch in ComputeXRay. - MatchManager: hit reveal broadcasts X-ray flash first, delays hider removal by hitRevealDelay so the glow is visible before the body vanishes. - MeshPainter reseed: in-place fast path avoids full GPU backend teardown on snapshot apply (no ~70MB RT churn), fixes spawn/paint-load hitch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
5b95cb7f56
commit
9290ef650b
10 files changed
+403
-23
No files matched your search
@@ -115,6 +115,12 @@ public class MatchManager : MonoBehaviour
|
||||
[Min(0f)]
|
||||
[SerializeField] private float shootCooldown = 0.4f;
|
||||
|
||||
[Tooltip("Seconds a shot hider stays lit with the X-ray glow before it is actually removed from play " +
|
||||
"(Classic: hidden as found; Conversion: respawned as a hunter). Gives the just-shot flash time to " +
|
||||
"be seen. The hider stays a live target during this window; 0 = remove instantly (no visible flash).")]
|
||||
[Min(0f)]
|
||||
[SerializeField] private float hitRevealDelay = 0.35f;
|
||||
|
||||
[Header("Concealment reveal")]
|
||||
[Tooltip("A hider whose ConcealmentMeter EmbeddedPercent reaches this value (while a match is running) is " +
|
||||
"revealed through walls with the material's X-ray glow, so nobody can hide by burying itself deep " +
|
||||
@@ -192,6 +198,9 @@ public class MatchManager : MonoBehaviour
|
||||
// empties. _phaseRoutine is the running Hide->Seek->Resolution coroutine (stopped if the match is ended
|
||||
// early via the authority's Back-to-Lobby).
|
||||
private readonly HashSet<ulong> _pendingHiders = new HashSet<ulong>();
|
||||
// Server-only. Hiders that were hit and are in their X-ray flash window, not yet removed. Kept out of the
|
||||
// seek-end check by staying in _pendingHiders; this set only dedupes a second shot during the flash.
|
||||
private readonly HashSet<ulong> _revealingHiders = new HashSet<ulong>();
|
||||
// Server-only. Live NGO clientId -> persistent per-install id, reported by each client on connect. The
|
||||
// clientId is ephemeral (reused after a disconnect); the value is stable across that client's restarts.
|
||||
private readonly Dictionary<ulong, string> _persistentIds = new Dictionary<ulong, string>();
|
||||
@@ -398,6 +407,7 @@ public class MatchManager : MonoBehaviour
|
||||
|
||||
// A hider that leaves mid-match can never be found - drop it so "all hiders found" can still trigger.
|
||||
_pendingHiders.Remove(clientId);
|
||||
_revealingHiders.Remove(clientId); // and out of the in-flight flash set (its resolve coroutine no-ops)
|
||||
// Free the ephemeral clientId -> identity mapping (the clientId will be reused by a later joiner).
|
||||
_persistentIds.Remove(clientId);
|
||||
|
||||
@@ -517,6 +527,7 @@ public class MatchManager : MonoBehaviour
|
||||
RespawnAll(id => hunterIds.Contains(id) ? hunterPrefab : hiderPrefab, matchSpawnCenter);
|
||||
|
||||
_pendingHiders.Clear();
|
||||
_revealingHiders.Clear();
|
||||
foreach (ulong id in _net.ConnectedClientsIds)
|
||||
if (!hunterIds.Contains(id)) _pendingHiders.Add(id);
|
||||
|
||||
@@ -656,13 +667,40 @@ public class MatchManager : MonoBehaviour
|
||||
MarkHiderFound(targetClientId);
|
||||
}
|
||||
|
||||
// Server-only. Resolves a hit on a hider for the active mode, and drops it from the pending set; the seek
|
||||
// loop ends the phase early once that empties (no hiders left to find/convert). Classic flags the avatar
|
||||
// found (replicated by its NetworkPlayerSetup -> free-cam); Conversion respawns it as a Hunter.
|
||||
// Server-only. Resolves a hit on a hider: flashes its X-ray glow on every client, then (after hitRevealDelay
|
||||
// so the flash is actually seen) drops it from the pending set and applies the mode outcome - Classic flags
|
||||
// the avatar found (replicated by its NetworkPlayerSetup -> free-cam); Conversion respawns it as a Hunter.
|
||||
// The hider stays in _pendingHiders during the flash so seek doesn't end early on the last hit; the seek
|
||||
// loop ends the phase once _pendingHiders empties (no hiders left to find/convert).
|
||||
private void MarkHiderFound(ulong hiderClientId)
|
||||
{
|
||||
_pendingHiders.Remove(hiderClientId);
|
||||
if (_revealingHiders.Contains(hiderClientId)) return; // already flashing / being resolved
|
||||
|
||||
if (_net.ConnectedClients.TryGetValue(hiderClientId, out var c) && c.PlayerObject)
|
||||
{
|
||||
var setup = c.PlayerObject.GetComponent<NetworkPlayerSetup>();
|
||||
if (setup) setup.FlashHitReveal(hitRevealDelay); // light it up on every client, now
|
||||
}
|
||||
|
||||
_revealingHiders.Add(hiderClientId);
|
||||
StartCoroutine(ResolveHitAfterReveal(hiderClientId));
|
||||
}
|
||||
|
||||
// Server-only. Waits out the reveal flash, then removes the hider and applies the mode outcome. Split from
|
||||
// MarkHiderFound so the glow is visible before the avatar leaves play (Classic hide / Conversion despawn).
|
||||
private IEnumerator ResolveHitAfterReveal(ulong hiderClientId)
|
||||
{
|
||||
if (hitRevealDelay > 0f) yield return new WaitForSeconds(hitRevealDelay);
|
||||
|
||||
_revealingHiders.Remove(hiderClientId);
|
||||
if (_net == null || !_net.IsServer) yield break;
|
||||
|
||||
_pendingHiders.Remove(hiderClientId);
|
||||
|
||||
// A Back-to-Lobby (EndMatch) during the flash tears the match down and respawns everyone; don't then
|
||||
// convert/found a stale avatar.
|
||||
if (Phase == MatchPhase.InMatch &&
|
||||
_net.ConnectedClients.TryGetValue(hiderClientId, out var c) && c.PlayerObject)
|
||||
{
|
||||
if (matchMode == MatchMode.Conversion)
|
||||
ConvertToHunter(hiderClientId, c.PlayerObject);
|
||||
@@ -672,6 +710,7 @@ public class MatchManager : MonoBehaviour
|
||||
if (setup) setup.ServerMarkFound();
|
||||
}
|
||||
}
|
||||
|
||||
string verb = matchMode == MatchMode.Conversion ? "converted to hunter" : "found";
|
||||
Debug.Log($"[MatchManager] Hider {hiderClientId} {verb} - {_pendingHiders.Count} hider(s) left.", this);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user