From f90cdae3c662f43fa96422e6f444b774de383657 Mon Sep 17 00:00:00 2001 From: vis2k Date: Thu, 21 Mar 2019 11:46:55 +0100 Subject: [PATCH] fix #384: duplicating scene objects at runtime is now detected and and error is shown. otherwise the user could instantiate scene objects at runtime, which would then send the sceneId to the client, then the client wouldn't know which of the multiple objects to use for the sceneId, resulting in things getting out of sync. --- Assets/Mirror/Runtime/NetworkIdentity.cs | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Assets/Mirror/Runtime/NetworkIdentity.cs b/Assets/Mirror/Runtime/NetworkIdentity.cs index 9d53d3715..0ac092cad 100644 --- a/Assets/Mirror/Runtime/NetworkIdentity.cs +++ b/Assets/Mirror/Runtime/NetworkIdentity.cs @@ -150,6 +150,34 @@ internal void RemoveObserverInternal(NetworkConnection conn) observers?.Remove(conn.connectionId); } + void Awake() + { + // detect runtime sceneId duplicates, e.g. if a user tries to + // Instantiate a sceneId object at runtime. if we don't detect it, + // then the client won't know which of the two objects to use for a + // SpawnSceneObject message, and it's likely going to be the wrong + // object. + // + // This might happen if for example we have a Dungeon GameObject + // which contains a Skeleton monster as child, and when a player + // runs into the Dungeon we create a Dungeon Instance of that + // Dungeon, which would duplicate a scene object. + // + // see also: https://github.com/vis2k/Mirror/issues/384 + if (Application.isPlaying && sceneId != 0) + { + if (sceneIds.TryGetValue(sceneId, out NetworkIdentity existing) && existing != this) + { + Debug.LogError(name + "'s sceneId: " + sceneId.ToString("X") + " is already taken by: " + existing.name + ". Don't call Instantiate for NetworkIdentities that were in the scene since the beginning (aka scene objects). Otherwise the client won't know which object to use for a SpawnSceneObject message."); + Destroy(gameObject); + } + else + { + sceneIds[sceneId] = this; + } + } + } + void OnValidate() { #if UNITY_EDITOR