EditorPlayModeSync
Synchronizes Play Mode enter/exit across multiple Unity Editor instances on the local network. Uses UDP broadcast on port 8052 to propagate state changes, enabling multi-instance testing workflows.
Definition
Namespace: Paragon.Core.Editor Assembly: Paragon.Editor.dll
[InitializeOnLoad]
public class EditorPlayModeSync : IDisposableAttributes: [InitializeOnLoad] — initializes via static constructor on editor load. Implements: IDisposable
Remarks
This utility is designed for multi-editor workflows where you need multiple Unity instances to enter or exit Play Mode simultaneously (e.g., testing networked multiplayer locally).
Initialization Flow
Static constructor runs on editor load (
[InitializeOnLoad])Resolves the project name via
ParagonPaths.Projectfor self-identificationSubscribes to
EditorApplication.playModeStateChangedto broadcast state changesSubscribes to
EditorApplication.updateto process received messagesCreates a UDP client bound to port 8052 with broadcast enabled
Message Protocol
Messages are plain ASCII strings in the format: {clientName}:{PlayModeStateChange}
ProjectA:EnteredPlayMode
Project A entered Play Mode
ProjectA:ExitingPlayMode
Project A is exiting Play Mode
Self-Filtering
Each editor identifies itself by its project name (ParagonPaths.Project). When a message is received with a matching client name, it is ignored to prevent feedback loops.
Delayed Execution
Play mode transitions triggered by remote messages are delayed by 1 second via Yield.WaitForEditorSeconds to ensure stable state before transitioning.
Quick Lookup
Enable enter-play sync
Set EditorPlayModeSync.SyncEnterPlay = true in Editor Preferences
Enable exit-play sync
Set EditorPlayModeSync.SyncExitPlay = true in Editor Preferences
Disable all syncing
Set both SyncEnterPlay and SyncExitPlay to false
UDP port
8052 (hardcoded)
Message format
{clientName}:{PlayModeStateChange}
Properties
SyncEnterPlay
bool
public static
When true, entering Play Mode in another editor triggers enter here. Persisted via [EditorPreference].
SyncExitPlay
bool
public static
When true, exiting Play Mode in another editor triggers exit here. Persisted via [EditorPreference].
Fields
port
int
private const
UDP broadcast port (8052)
udpClient
UdpClient
private static
The UDP client for sending and receiving broadcasts
clientName
string
private static readonly
This editor's project name for self-identification
syncedPlayMode
PlayModeStateChange?
private static
Queued play mode change received from another editor
Methods
Connect (private static)
Creates and binds the UdpClient to port 8052 with ReuseAddress and EnableBroadcast, then begins async receive.
Broadcast (private static)
Sends a UDP broadcast message. No-ops if both sync preferences are disabled.
ReceiveCallback (private static)
Async callback for UdpClient.BeginReceive. Decodes the message and passes to OnMessageReceived, then re-registers for the next receive.
OnMessageReceived (private static)
Parses the {clientName}:{state} message. Ignores messages from self. Sets syncedPlayMode for processing in the next Update.
Update (private static)
Called every editor frame via EditorApplication.update. If syncedPlayMode is set:
ExitingPlayMode+SyncExitPlayenabled + currently playing → exit play mode after 1sEnteredPlayMode+SyncEnterPlayenabled + not playing → enter play mode after 1s
Disconnect (private static)
Closes and nullifies the UDP client.
IDisposable.Dispose (explicit)
Calls Disconnect() to clean up the UDP client.
Common Pitfalls
Port conflict Port 8052 is hardcoded. If another application uses this port, the UdpClient.Bind will throw a SocketException. There is no fallback port mechanism.
Firewall blocking UDP broadcast may be blocked by firewall rules. Ensure port 8052 UDP is allowed for local network broadcast.
No encryption or authentication Messages are plain ASCII over UDP broadcast. Any application on the local network can send messages on port 8052 that will be interpreted as play mode commands.
Feedback loop prevention relies on project name If two editors share the same ParagonPaths.Project value, they will filter out each other's messages as "self" and syncing will not work.
See Also
EditorPlayModeSync Overview — subsystem overview
Yield — async delay via
WaitForEditorSeconds
Last updated