Fix stuck conversion render-gate on mid-settle disable/disconnect
The freshly converted hunter's body was hidden for the settle window via a WaitForSeconds coroutine. If the object was disabled or the converting owner disconnected mid-settle, the coroutine was stranded and _renderGate stayed true forever, leaving the avatar invisible on every remote. Replace it with a frame-driven Time.time deadline (_renderGateUntil) lifted in UpdateVisibility, which runs every frame the component is active and can never get stuck. Remove the coroutine and the now-unused System.Collections using. Visible behaviour in the normal case is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
0c0a250015
commit
17bb37cb92
1 file changed
+7
-10
@@ -1,4 +1,3 @@
|
|||||||
using System.Collections;
|
|
||||||
using Unity.Netcode;
|
using Unity.Netcode;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -105,6 +104,7 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
|||||||
private bool _visibilityApplied;
|
private bool _visibilityApplied;
|
||||||
private bool _lastVisible = true;
|
private bool _lastVisible = true;
|
||||||
private bool _renderGate; // conversion: body force-hidden until the fresh hunter has settled into place
|
private bool _renderGate; // conversion: body force-hidden until the fresh hunter has settled into place
|
||||||
|
private float _renderGateUntil; // Time.time deadline that lifts _renderGate; frame-driven (see UpdateVisibility) so a mid-settle disable/despawn can't strand the body hidden forever
|
||||||
|
|
||||||
private MeshPainter _painter; // owns the per-avatar material instance carrying _XRayColor
|
private MeshPainter _painter; // owns the per-avatar material instance carrying _XRayColor
|
||||||
private ConcealmentMeter _concealment; // owner-only embedded-percent source (disabled on remotes)
|
private ConcealmentMeter _concealment; // owner-only embedded-percent source (disabled on remotes)
|
||||||
@@ -170,8 +170,8 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
|||||||
if (!float.IsNaN(_spawnOverride.Value.x))
|
if (!float.IsNaN(_spawnOverride.Value.x))
|
||||||
{
|
{
|
||||||
_renderGate = true;
|
_renderGate = true;
|
||||||
|
_renderGateUntil = Time.time + conversionRevealDelay;
|
||||||
SetBodyRenderers(false); // hide immediately, before the first UpdateVisibility runs
|
SetBodyRenderers(false); // hide immediately, before the first UpdateVisibility runs
|
||||||
StartCoroutine(RevealAfterSettle());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,6 +262,11 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
|||||||
// never fights the FirstPersonController's own-body self-hide.
|
// never fights the FirstPersonController's own-body self-hide.
|
||||||
private void UpdateVisibility()
|
private void UpdateVisibility()
|
||||||
{
|
{
|
||||||
|
// Frame-driven gate expiry (replaces a WaitForSeconds coroutine): a coroutine is stranded if the
|
||||||
|
// object is disabled or the converting owner disconnects mid-settle, leaving the body hidden forever.
|
||||||
|
// Time.time lifts it here every frame the component runs, so the gate can never get stuck.
|
||||||
|
if (_renderGate && Time.time >= _renderGateUntil) _renderGate = false;
|
||||||
|
|
||||||
bool found = _isFound.Value;
|
bool found = _isFound.Value;
|
||||||
if (IsOwner && !found) return;
|
if (IsOwner && !found) return;
|
||||||
|
|
||||||
@@ -281,14 +286,6 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
|||||||
_visibilityApplied = true;
|
_visibilityApplied = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conversion: drop the render gate after the settle delay so the next visibility pass reveals the hunter
|
|
||||||
// at its final, replicated position. Per-client and cosmetic (each client reveals on its own clock).
|
|
||||||
private IEnumerator RevealAfterSettle()
|
|
||||||
{
|
|
||||||
yield return new WaitForSeconds(conversionRevealDelay);
|
|
||||||
_renderGate = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decides whether THIS avatar's body is rendered for the local viewer. Hunters and non-match avatars are
|
// Decides whether THIS avatar's body is rendered for the local viewer. Hunters and non-match avatars are
|
||||||
// always visible; a Classic-found hider is always hidden; Resolution reveals everyone. The rest is the
|
// always visible; a Classic-found hider is always hidden; Resolution reveals everyone. The rest is the
|
||||||
// hider-visibility matrix per mode:
|
// hider-visibility matrix per mode:
|
||||||
|
|||||||
Reference in new issue
Block a user