Add conversion statues shown in resolution phase
In Conversion mode, capture a snapshot (pose index + paint) of each hider at conversion time and materialize a frozen, painted statue at the found spot for the resolution phase, independent of the now-hunter avatar. - MatchStatue.cs (new): server-init pose/paint, network-driven pose then freeze, reveal-gate (hidden until paint applied), kills inherited sim. - PlayerPaintSync: _isStatue (sibling auto-detect) suppresses the three auto-behaviours so MatchStatue drives the paint flow deterministically. - MatchManager: statuePrefab; capture in ConvertToHunter; spawn on resolution enter; despawn + record clear on EndMatch/teardown/start. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
0a1e286a34
commit
0f108fce47
4 files changed
+232
-5
No files matched your search
@@ -138,7 +138,18 @@ public class PlayerPaintSync : NetworkBehaviour
|
||||
// spawn), applied in LateUpdate once this fresh painter is ready. Null = nothing to carry.
|
||||
private byte[] _pendingCarry;
|
||||
|
||||
private void Awake() => _painter = GetComponentInChildren<MeshPainter>(true);
|
||||
// True when this receiver sits on a MatchStatue: a statue drives its painting explicitly (the server
|
||||
// loads the captured snapshot then broadcasts it), so the owner-carry take, the client auto snapshot-
|
||||
// request and the no-carry blank publish are all suppressed to keep them from racing that push.
|
||||
private bool _isStatue;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_painter = GetComponentInChildren<MeshPainter>(true);
|
||||
// Detected from the sibling component so no inspector flag can be forgotten on the prefab.
|
||||
var statue = GetComponentInChildren<MatchStatue>(true);
|
||||
_isStatue = statue;
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
@@ -151,7 +162,7 @@ public class PlayerPaintSync : NetworkBehaviour
|
||||
_painter.OnHistoryCheckpoint += OnLocalCheckpoint;
|
||||
_painter.OnHistoryRestore += OnLocalRestore;
|
||||
|
||||
if (MatchManager.Instance) _pendingCarry = MatchManager.Instance.TakeCarriedPaint();
|
||||
if (MatchManager.Instance && !_isStatue) _pendingCarry = MatchManager.Instance.TakeCarriedPaint();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -178,8 +189,8 @@ public class PlayerPaintSync : NetworkBehaviour
|
||||
_heightApplyPending = true;
|
||||
|
||||
// The host's replica already holds the full paint via the live stream; only a genuine
|
||||
// late joiner needs the baseline pulled over.
|
||||
if (!IsServer)
|
||||
// late joiner needs the baseline pulled over. A statue never pulls - the server pushes it.
|
||||
if (!IsServer && !_isStatue)
|
||||
{
|
||||
_awaitingSnapshot = true;
|
||||
if (logSync) LogSync("late joiner: requesting baseline snapshot");
|
||||
@@ -293,7 +304,7 @@ public class PlayerPaintSync : NetworkBehaviour
|
||||
// avatar must still hand every peer an explicit (blank) snapshot, otherwise its body stays hidden
|
||||
// forever behind the receiver-side reveal gate. Carry/manual-load already publish (and set the
|
||||
// cutoff), so this only fires for the no-carry case.
|
||||
if (_publishedCutoff.Value < 0 && _pendingCarry == null && _painter && _painter.IsPaintReady)
|
||||
if (_publishedCutoff.Value < 0 && _pendingCarry == null && !_isStatue && _painter && _painter.IsPaintReady)
|
||||
BroadcastLoadedPaint();
|
||||
|
||||
// Delta-only publish: the NetworkVariable dirties only on an actual change.
|
||||
|
||||
Reference in new issue
Block a user