Docs: reduce over-documentation across gameplay scripts
Trim restated narration, dead commented-out code, and oversized class headers; keep all why-comments (authority, timing, edge cases), tooltips, and serialization caveats. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
882d30797e
commit
066e308cde
21 files changed
+478
-902
No files matched your search
@@ -71,9 +71,8 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
/// neutral lobby Player prefab (full mode set). Baked per prefab variant.</summary>
|
||||
public bool ScopedModes => scopedModes;
|
||||
|
||||
// Server-authoritative "this hider has been shot/found". Server-write (a hunter's hit is validated on
|
||||
// the server, not by the hider's owner); read by everyone. When it flips true the body is hidden on
|
||||
// every client and the owning client drops into free-cam-only spectating. Stays false on hunters/lobby.
|
||||
// Server-authoritative "this hider has been shot/found" (a hit is validated on the server, not by the
|
||||
// hider's owner). When it flips true the body hides on every client and the owner drops to spectating.
|
||||
private readonly NetworkVariable<bool> _isFound =
|
||||
new NetworkVariable<bool>(false, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
|
||||
|
||||
@@ -81,25 +80,21 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
/// target that is already out of play.</summary>
|
||||
public bool IsFound => _isFound.Value;
|
||||
|
||||
// Owner-authoritative "this hider is buried too deep" flag. Only the OWNER runs the ConcealmentMeter
|
||||
// (it is disabled on remotes), so the owner compares its EmbeddedPercent against MatchManager's
|
||||
// threshold and writes this; every client reads it to switch the through-walls X-ray glow on/off for
|
||||
// this avatar. Stays false on hunters / the lobby avatar and whenever no match is running.
|
||||
// Owner-authoritative "this hider is buried too deep" flag: only the OWNER runs the ConcealmentMeter,
|
||||
// so it compares EmbeddedPercent against the threshold and writes; every client reads it to switch
|
||||
// the through-walls X-ray glow.
|
||||
private readonly NetworkVariable<bool> _embeddedReveal =
|
||||
new NetworkVariable<bool>(false, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
|
||||
|
||||
// Conversion-mode in-place respawn position. The owner holds authority over the NetworkTransform, so the
|
||||
// server's Instantiate position is NOT honoured on the owner (it would otherwise snap to the prefab origin,
|
||||
// 0,0,0). The server writes the tagged world position here in its OnNetworkSpawn so it rides the initial
|
||||
// spawn snapshot to the owner, which then restores it itself. The NaN sentinel means "no override" (a
|
||||
// normal lobby/match-start spawn) -> the owner runs its usual spawn-area/ring placement.
|
||||
// Conversion-mode in-place respawn position. The owner holds transform authority, so the server's
|
||||
// Instantiate position is NOT honoured there; the server writes the tagged position here so it rides
|
||||
// the spawn snapshot and the owner restores it itself. NaN sentinel = no override (normal placement).
|
||||
private static readonly Vector3 NoSpawnOverride = new Vector3(float.NaN, float.NaN, float.NaN);
|
||||
private readonly NetworkVariable<Vector3> _spawnOverride =
|
||||
new NetworkVariable<Vector3>(NoSpawnOverride, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
|
||||
|
||||
// Server-only handoff from MatchManager.ConvertToHunter: the world position the converted hunter must keep.
|
||||
// Pushed into the replicated _spawnOverride during OnNetworkSpawn (where the variable is spawned and the
|
||||
// server is allowed to write it - a pre-spawn write is silently dropped); a plain field needs no replication.
|
||||
// Server-only handoff from MatchManager.ConvertToHunter, pushed into _spawnOverride during
|
||||
// OnNetworkSpawn (a pre-spawn write to the NetworkVariable is silently dropped).
|
||||
private Vector3? _conversionSpawnPos;
|
||||
|
||||
/// <summary>Server-only. Call on a freshly-instantiated Conversion hunter BEFORE spawning it so the owner
|
||||
@@ -126,8 +121,7 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
_isFound.OnValueChanged += OnFoundChanged;
|
||||
if (_isFound.Value) ApplyFound(); // defensive: an avatar is never normally spawned already-found
|
||||
|
||||
// Server pushes a Conversion respawn's tagged position into the replicated override before the spawn
|
||||
// snapshot goes out, so the owner (which owns the transform) can restore it in its own OnNetworkSpawn.
|
||||
// Push the Conversion position into the replicated override before the spawn snapshot goes out.
|
||||
if (IsServer && _conversionSpawnPos.HasValue)
|
||||
_spawnOverride.Value = _conversionSpawnPos.Value;
|
||||
|
||||
@@ -135,10 +129,8 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
|
||||
if (IsOwner)
|
||||
{
|
||||
// A Conversion-mode tag respawns the hider as this Hunter variant in place. The owner-authoritative
|
||||
// transform ignores the server's Instantiate position, so without help the owner snaps to the prefab
|
||||
// origin (0,0,0); the server delivers the tagged position via _spawnOverride, restored here. A normal
|
||||
// spawn (NaN override) runs the usual spawn-area/ring placement instead.
|
||||
// Conversion respawn: restore the server-tagged position (the owner-authoritative transform
|
||||
// ignores the server's Instantiate pos); NaN override = normal spawn placement.
|
||||
Vector3 overridePos = _spawnOverride.Value;
|
||||
if (float.IsNaN(overridePos.x))
|
||||
PlaceAtSpawn();
|
||||
@@ -157,36 +149,25 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
var cc = GetComponent<CharacterController>();
|
||||
if (cc) cc.enabled = false;
|
||||
|
||||
// Owner cleanup: the concealment meter is a per-frame skinned-mesh bake + voxelization +
|
||||
// physics overlap whose result only feeds the LOCAL player (HUD / gameplay + the embedded-reveal
|
||||
// flag). A remote avatar's concealment is computed on its own owner's machine, so running it here
|
||||
// is pure wasted CPU.
|
||||
// The concealment meter (per-frame bake + voxelization + overlap) only feeds the LOCAL player;
|
||||
// a remote's concealment is computed on its own owner's machine, so here it is wasted CPU.
|
||||
if (_concealment) _concealment.enabled = false;
|
||||
|
||||
// NOTE: SkinnedColliderBaker deliberately stays ENABLED on remotes. MeshPainter's stamp replay
|
||||
// (ApplyNetworkStamp -> DrawBrushGpu) rasterizes the baker's live, per-frame BakedMesh to map a
|
||||
// 3D brush placement into UV space; freezing the bake would mis-map replicated paint onto any
|
||||
// non-rest pose. Its bake is the necessary cost of correct remote paint, not wasted work.
|
||||
// NOTE: SkinnedColliderBaker deliberately stays ENABLED on remotes - stamp replay rasterizes its
|
||||
// live per-frame BakedMesh to map 3D brush placements into UV space; freezing the bake would
|
||||
// mis-map replicated paint onto any non-rest pose.
|
||||
|
||||
// The rig must keep evaluating even while this body is HIDDEN on the local client. During the hide
|
||||
// phase a hider's body is hidden on hunter clients (UpdateVisibility sets renderer.enabled = false),
|
||||
// and a remote can also sit off-screen. The avatar's Animator is authored as CullUpdateTransforms,
|
||||
// which STOPS writing the bone transforms whenever its renderer isn't visible. PlayerPoseController
|
||||
// drives the rig through a PlayableGraph on this Animator and resets un-keyed bones to rest every
|
||||
// frame, so a culled Animator leaves the rig frozen at the rest/T-pose. SkinnedColliderBaker then
|
||||
// bakes that wrong pose, and any paint stamp replicated during the hidden window lands on the wrong
|
||||
// body part - a desync that persists once the body is shown again. Forcing AlwaysAnimate keeps the
|
||||
// pose (and thus the baked mesh paint replay rasterizes) correct regardless of visibility. Remote
|
||||
// replicas only: an owner is never hidden from its own camera.
|
||||
// Force AlwaysAnimate so the rig keeps evaluating while this body is HIDDEN locally (hide phase /
|
||||
// off-screen): the authored CullUpdateTransforms stops writing bones when the renderer isn't
|
||||
// visible, the pose reset then freezes the rig at rest, SkinnedColliderBaker bakes that wrong
|
||||
// pose, and replicated paint lands on the wrong body part - a desync that persists once shown
|
||||
// again. Remote replicas only (an owner is never hidden from its own camera).
|
||||
foreach (var anim in GetComponentsInChildren<Animator>(true))
|
||||
anim.cullingMode = AnimatorCullingMode.AlwaysAnimate;
|
||||
|
||||
// Conversion mode: a hider shot during Seek is despawned and respawned in place as this Hunter
|
||||
// variant. Keep the fresh hunter hidden on this (remote) client for a short settle window so nobody
|
||||
// sees it appear or interpolate from the spawn frame - the shot hider is already gone, then the
|
||||
// hunter cleanly materializes in its place. Detected via the replicated override the server wrote
|
||||
// above; it rides the spawn snapshot, so it is already valid here. The owner returned early above
|
||||
// (first-person, own body self-hidden), so it is never gated.
|
||||
// Conversion: keep the fresh in-place hunter hidden on this remote client for a short settle
|
||||
// window so nobody sees it pop in or interpolate from the spawn frame. Detected via the
|
||||
// replicated override (already valid here); the owner returned early above, so it is never gated.
|
||||
if (!float.IsNaN(_spawnOverride.Value.x))
|
||||
{
|
||||
_renderGate = true;
|
||||
@@ -243,12 +224,10 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
UpdateResolutionFreeze();
|
||||
}
|
||||
|
||||
// Per-client. During the resolution phase every still-in-play hider is frozen in place on every machine:
|
||||
// its pose graph holds the current frame (PlayerPoseController.Frozen) and, on the owning client, its
|
||||
// movement input is cut (ControlEnabled) so the owner-authoritative transform stops and replicates as
|
||||
// frozen. Mirrors the resolution X-ray reveal predicate. The pose flag is change-guarded (toggled only on
|
||||
// a transition); the owner's ControlEnabled is re-asserted every frozen frame so a stray mode toggle can't
|
||||
// quietly re-enable movement during the reveal. Nothing is restored — EndMatch despawns this avatar.
|
||||
// Per-client. During Resolution every still-in-play hider is frozen: the pose graph holds the frame
|
||||
// (PlayerPoseController.Frozen, change-guarded) and the owner's movement input is cut - re-asserted
|
||||
// every frozen frame so a stray mode toggle can't quietly re-enable movement during the reveal.
|
||||
// Nothing is restored: EndMatch despawns this avatar.
|
||||
private void UpdateResolutionFreeze()
|
||||
{
|
||||
bool freeze = ComputeResolutionFreeze();
|
||||
@@ -277,10 +256,8 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
}
|
||||
|
||||
// Per-client visibility: each machine decides whether to render THIS avatar's body from the LOCAL
|
||||
// viewer's perspective (hunter bodies are always visible; only hider bodies are ever hidden). A found
|
||||
// hider (Classic) is hidden for everyone. Otherwise it depends on the match MODE - see ComputeVisible.
|
||||
// The local owner's own body is left alone unless found, so this never fights the FirstPersonController's
|
||||
// own-body self-hide.
|
||||
// viewer's perspective (see ComputeVisible). The owner's own body is left alone unless found, so this
|
||||
// never fights the FirstPersonController's own-body self-hide.
|
||||
private void UpdateVisibility()
|
||||
{
|
||||
bool found = _isFound.Value;
|
||||
@@ -341,10 +318,8 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
return true;
|
||||
}
|
||||
|
||||
// Owner-only. Publishes whether this hider is buried too deep to the replicated flag every client reads.
|
||||
// Only a Hider avatar during a running match qualifies (the anti-burrow reveal targets hiders); the meter
|
||||
// runs owner-side only, so this is where EmbeddedPercent is available. Cheap: a bool compare, one network
|
||||
// write only on an actual edge (NetworkVariable dirties on assignment, so guard against no-op writes).
|
||||
// Owner-only (the meter runs owner-side, so EmbeddedPercent is only available here). Publishes the
|
||||
// buried-too-deep flag; one network write per actual edge (guarded - the variable dirties on assignment).
|
||||
private void UpdateEmbeddedReveal()
|
||||
{
|
||||
if (!IsOwner) return;
|
||||
@@ -358,10 +333,9 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
if (over != _embeddedReveal.Value) _embeddedReveal.Value = over;
|
||||
}
|
||||
|
||||
// Per-client. Switches this avatar's see-through-walls X-ray glow on/off by driving the material's
|
||||
// _XRayColor alpha (via MeshPainter). Two independent triggers, OR-combined: the replicated embedded
|
||||
// flag (a buried hider, from its owner) and the local resolution phase (every un-found hider is revealed
|
||||
// to everyone at the end). Change-guarded so the material is only touched on an actual transition.
|
||||
// Per-client X-ray glow via the material's _XRayColor alpha (through MeshPainter). Two OR-combined
|
||||
// triggers: the replicated embedded flag and the local resolution phase. Change-guarded so the
|
||||
// material is only touched on an actual transition.
|
||||
private void UpdateXRayReveal()
|
||||
{
|
||||
if (!_painter) return;
|
||||
@@ -397,11 +371,9 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Places the freshly-spawned owner. Prefers this avatar's role-specific spawn area (Hunter/Hider tag),
|
||||
/// then the shared <see cref="spawnAreaTag"/> area; if a matching area is loaded the owner drops at a
|
||||
/// random point inside that collider (designer-authored spawn region). With no area present it falls back
|
||||
/// to the deterministic client-id ring. Owner-authoritative either way - the NetworkTransform replicates
|
||||
/// the result, and PlayerCharacterController captures it on its first Update as the kill-plane rescue target.
|
||||
/// Places the freshly-spawned owner: role-specific spawn area first, then the shared area (a random
|
||||
/// point inside the collider), falling back to the deterministic client-id ring. Owner-authoritative -
|
||||
/// the NetworkTransform replicates the result.
|
||||
/// </summary>
|
||||
private void PlaceAtSpawn()
|
||||
{
|
||||
@@ -412,13 +384,10 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-asserts the server-delivered Conversion position on the owner. The owner-authoritative
|
||||
/// NetworkTransform makes the owner's transform the source of truth, so the server's Instantiate
|
||||
/// position alone doesn't stick - the owner must set it here, BEFORE PlayerCharacterController's first
|
||||
/// Update snapshots the kill-plane rescue target (otherwise a hider tagged mid-wall-climb spawns, falls
|
||||
/// off the fresh hunter capsule below the kill plane, and is rescued to the still-zero default target =
|
||||
/// origin). The CharacterController is toggled around the write because it otherwise overrides direct
|
||||
/// transform writes (same pattern as PlaceOnSpawnRing/PlaceRandomlyInArea).
|
||||
/// Re-asserts the server-delivered Conversion position on the owner (whose transform is the source of
|
||||
/// truth), BEFORE PlayerCharacterController's first Update snapshots the kill-plane rescue target -
|
||||
/// otherwise a hider tagged mid-climb could fall and be rescued to the still-zero default (origin).
|
||||
/// The CharacterController is toggled around the write (it overrides direct transform writes).
|
||||
/// </summary>
|
||||
private void ApplyOwnerPosition(Vector3 worldPos)
|
||||
{
|
||||
@@ -454,11 +423,9 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Drops the owner at a random point inside the spawn-area collider. X/Z are sampled within the
|
||||
/// collider's footprint (rejection-sampled against the convex shape so the irregular outline is honoured,
|
||||
/// not just its bounding box); Y sits a touch above the area floor so gravity settles the avatar onto the
|
||||
/// ground. The CharacterController is toggled around the move because it otherwise overrides direct
|
||||
/// transform writes (same pattern as <see cref="PlaceOnSpawnRing"/>).
|
||||
/// Drops the owner at a random point inside the spawn-area collider: X/Z rejection-sampled against
|
||||
/// the convex shape (honours the real outline, not just the AABB), Y a touch above the floor so
|
||||
/// gravity settles. The CharacterController is toggled around the move (see ApplyOwnerPosition).
|
||||
/// </summary>
|
||||
private void PlaceRandomlyInArea(Collider area)
|
||||
{
|
||||
@@ -496,11 +463,8 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
|
||||
/// <summary>
|
||||
/// Offsets the freshly-spawned owner onto a deterministic ring keyed by its client id so avatars
|
||||
/// don't pile up at the shared prefab spawn point. Id 0 (the host) keeps the origin so single-player
|
||||
/// "host alone" is unchanged; every later joiner takes the next ring slot, stepping the radius out
|
||||
/// once a ring fills. Only X/Z are shifted (gravity settles Y), and the CharacterController is toggled
|
||||
/// around the move because it otherwise overrides direct transform writes. Owner-authoritative, so the
|
||||
/// NetworkTransform replicates the placement outward.
|
||||
/// don't pile up at the shared prefab spawn point. Id 0 (host) keeps the origin; later joiners take
|
||||
/// ring slots, stepping the radius out once a ring fills. Only X/Z shift (gravity settles Y).
|
||||
/// </summary>
|
||||
private void PlaceOnSpawnRing()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user