Sync emission intensity across the network
Replicate MeshPainter.emissionIntensity (a global material multiplier, not baked into the paint maps) as an owner-authoritative NetworkVariable<float> on PlayerPaintSync. The owner publishes on change; remotes subscribe, seed the current value on spawn (covers late-join) and let MeshPainter's per-frame RefreshEmissionColor push it onto the material. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
10f2518640
commit
dec537a60f
1 file changed
+30
-1
@@ -16,6 +16,11 @@ using UnityEngine;
|
|||||||
/// throttled to respect the transport's reliable window), buffers any live stamps that arrive during
|
/// throttled to respect the transport's reliable window), buffers any live stamps that arrive during
|
||||||
/// the transfer, and after applying the snapshot replays the buffered stamps newer than the snapshot's
|
/// the transfer, and after applying the snapshot replays the buffered stamps newer than the snapshot's
|
||||||
/// cutoff sequence - so no stroke is lost or double-applied across the join window.
|
/// cutoff sequence - so no stroke is lost or double-applied across the join window.
|
||||||
|
///
|
||||||
|
/// Emission intensity is the one paint property that is NOT baked into the maps (it's a global
|
||||||
|
/// multiplier on the material's _EmissionColor), so it can't ride the stamp/snapshot path. It rides its
|
||||||
|
/// own owner-authoritative NetworkVariable; the remote painter's per-frame RefreshEmissionColor picks up
|
||||||
|
/// the applied field, and a late joiner gets the current value on spawn for free.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DisallowMultipleComponent]
|
[DisallowMultipleComponent]
|
||||||
public class PlayerPaintSync : NetworkBehaviour
|
public class PlayerPaintSync : NetworkBehaviour
|
||||||
@@ -36,6 +41,12 @@ public class PlayerPaintSync : NetworkBehaviour
|
|||||||
private MeshPainter _painter;
|
private MeshPainter _painter;
|
||||||
private readonly List<PaintStampNet> _pending = new List<PaintStampNet>();
|
private readonly List<PaintStampNet> _pending = new List<PaintStampNet>();
|
||||||
|
|
||||||
|
// Global emission-intensity multiplier (MeshPainter.emissionIntensity) — a per-player material value,
|
||||||
|
// not part of the painted maps. Owner-authoritative like the rest; the remote applies it to its
|
||||||
|
// painter, whose per-frame RefreshEmissionColor pushes it to the material (no extra material poke).
|
||||||
|
private readonly NetworkVariable<float> _emissionIntensity =
|
||||||
|
new(1f, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner);
|
||||||
|
|
||||||
// Monotonic batch counter on the owner; on every peer, the highest batch sequence accounted for
|
// Monotonic batch counter on the owner; on every peer, the highest batch sequence accounted for
|
||||||
// (applied to a remote replica / sent by the owner). Used as the snapshot's cutoff marker.
|
// (applied to a remote replica / sent by the owner). Used as the snapshot's cutoff marker.
|
||||||
private int _seq;
|
private int _seq;
|
||||||
@@ -67,6 +78,10 @@ public class PlayerPaintSync : NetworkBehaviour
|
|||||||
// clobber the local player's saved paint on teardown (same fix as the pose system).
|
// clobber the local player's saved paint on teardown (same fix as the pose system).
|
||||||
_painter.persistPaint = false;
|
_painter.persistPaint = false;
|
||||||
|
|
||||||
|
// Track the owner's emission intensity; seed the current (late-join) value right away.
|
||||||
|
_emissionIntensity.OnValueChanged += OnEmissionChanged;
|
||||||
|
_painter.emissionIntensity = _emissionIntensity.Value;
|
||||||
|
|
||||||
// The server (host) has been present since the start, so its replica already holds the full
|
// The server (host) has been present since the start, so its replica already holds the full
|
||||||
// paint via the live stream; only a genuine late joiner needs the baseline pulled over.
|
// paint via the live stream; only a genuine late joiner needs the baseline pulled over.
|
||||||
if (!IsServer)
|
if (!IsServer)
|
||||||
@@ -81,6 +96,12 @@ public class PlayerPaintSync : NetworkBehaviour
|
|||||||
{
|
{
|
||||||
if (_painter && IsOwner)
|
if (_painter && IsOwner)
|
||||||
_painter.OnStampCommitted -= OnStampCommitted;
|
_painter.OnStampCommitted -= OnStampCommitted;
|
||||||
|
_emissionIntensity.OnValueChanged -= OnEmissionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEmissionChanged(float previous, float current)
|
||||||
|
{
|
||||||
|
if (_painter) _painter.emissionIntensity = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Live stamp stream (owner -> server -> remotes) ----
|
// ---- Live stamp stream (owner -> server -> remotes) ----
|
||||||
@@ -100,7 +121,15 @@ public class PlayerPaintSync : NetworkBehaviour
|
|||||||
_awaitingSnapshot = false;
|
_awaitingSnapshot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsOwner || _pending.Count == 0)
|
if (!IsOwner)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Publish the owner's global emission intensity when the HUD slider changes it (delta-only; the
|
||||||
|
// NetworkVariable dirties only on an actual change, so assigning the same value is a no-op).
|
||||||
|
if (_painter && _emissionIntensity.Value != _painter.emissionIntensity)
|
||||||
|
_emissionIntensity.Value = _painter.emissionIntensity;
|
||||||
|
|
||||||
|
if (_pending.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int seq = ++_seq;
|
int seq = ++_seq;
|
||||||
|
|||||||
Reference in new issue
Block a user