Sync paint strokes across the network via command replication

Replicate brush strokes as self-contained commands instead of texture
pixels: the owner emits each committed stamp (local placement plus brush
state, byte-quantized) and remotes replay it through the same draw path,
reproducing identical maps without streaming megabytes.

- MeshPainter.Net.cs: PaintStampNet serializable stamp, OnStampCommitted
  owner-capture event (no-op without listener), ApplyNetworkStamp remote
  replay, seedable spray for deterministic speckle.
- MeshPainter.cs: emit stamp after drawing, seed spray only when synced.
- PlayerPaintSync.cs: NetworkBehaviour batching owner stamps reliably
  (ServerRpc -> ClientRpc) with echo guard; remote disables local painting.
- Player/Hider/Hunter prefabs: PlayerPaintSync plus NGO GlobalObjectIdHash.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-06-27 15:02:33 +02:00
1 parent 7f2f4e5999
commit 69e185d969
8 files changed
+285 -6

No files matched your search

+5 -1
View File
@@ -12,13 +12,17 @@ PrefabInstance:
propertyPath: scale
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 1557561356852236266, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
propertyPath: GlobalObjectIdHash
value: 708302045
objectReference: {fileID: 0}
- target: {fileID: 4587432968399885263, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5384024074013944205, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
propertyPath: m_Name
value: Player Variant
value: Hider
objectReference: {fileID: 0}
- target: {fileID: 6997860362608943113, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
propertyPath: m_LocalScale.x
+4
View File
@@ -16,6 +16,10 @@ PrefabInstance:
propertyPath: sprintSpeedMultiplier
value: 2
objectReference: {fileID: 0}
- target: {fileID: 1557561356852236266, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
propertyPath: GlobalObjectIdHash
value: 1884035523
objectReference: {fileID: 0}
- target: {fileID: 5384024074013944205, guid: 97017ed3bb40aff4e885440d9a7336ee, type: 3}
propertyPath: m_Name
value: Hunter
+18 -3
View File
@@ -49,6 +49,7 @@ GameObject:
- component: {fileID: 6847253018511389861}
- component: {fileID: 8574096554986372233}
- component: {fileID: 8646586982149381366}
- component: {fileID: 4234684093581208771}
m_Layer: 0
m_Name: Player
m_TagString: Player
@@ -111,7 +112,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 463b6be548abf464287096e1e92fcd01, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::PlayerCharacterController
persistPlayer: 1
persistPlayer: 0
playerSaveId:
moveSpeed: 2
sprintSpeedMultiplier: 3.2
@@ -224,7 +225,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d5a57f767e5e46a458fc5d3c628d0cbb, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.Netcode.Runtime::Unity.Netcode.NetworkObject
GlobalObjectIdHash: 0
GlobalObjectIdHash: 1963377418
InScenePlacedSourceGlobalObjectIdHash: 0
DeferredDespawnTick: 0
Ownership: 1
@@ -310,6 +311,20 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::PlayerAnimationSync
ShowTopMostFoldoutHeaderGroup: 1
--- !u!114 &4234684093581208771
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5384024074013944205}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f1b1a094f669d6b458370f63773462ed, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::PlayerPaintSync
ShowTopMostFoldoutHeaderGroup: 1
maxStampsPerFrame: 64
--- !u!1 &6840099669803454162
GameObject:
m_ObjectHideFlags: 0
@@ -437,7 +452,7 @@ MonoBehaviour:
brushShader: {fileID: 0}
dilateShader: {fileID: 0}
packMsShader: {fileID: 0}
persistPaint: 1
persistPaint: 0
saveId:
pipette: 0
spray: 0