diff --git a/Assets/Mirror/Runtime/NetworkClient.cs b/Assets/Mirror/Runtime/NetworkClient.cs index ae09f5f7d..060ec9d7b 100644 --- a/Assets/Mirror/Runtime/NetworkClient.cs +++ b/Assets/Mirror/Runtime/NetworkClient.cs @@ -1144,21 +1144,6 @@ static NetworkIdentity GetAndRemoveSceneObject(ulong sceneId) return null; } - // Checks if identity is not spawned yet, not hidden and has sceneId - // TODO merge with ValidateSceneObject on server - static bool IsSceneObject(NetworkIdentity identity) - { - // not spawned yet, not hidden, etc.? - - // need to ensure it's not active yet because - // PrepareToSpawnSceneObjects may be called multiple times in case - // the ObjectSpawnStarted message is received multiple times. - return !identity.gameObject.activeSelf && - identity.gameObject.hideFlags != HideFlags.NotEditable && - identity.gameObject.hideFlags != HideFlags.HideAndDontSave && - identity.sceneId != 0; - } - /// Call this after loading/unloading a scene in the client after connection to register the spawnable objects public static void PrepareToSpawnSceneObjects() { @@ -1170,7 +1155,11 @@ public static void PrepareToSpawnSceneObjects() foreach (NetworkIdentity identity in allIdentities) { // add all unspawned NetworkIdentities to spawnable objects - if (IsSceneObject(identity)) + // need to ensure it's not active yet because + // PrepareToSpawnSceneObjects may be called multiple times in case + // the ObjectSpawnStarted message is received multiple times. + if (Utils.IsSceneObject(identity) && + !identity.gameObject.activeSelf) { if (spawnableObjects.TryGetValue(identity.sceneId, out NetworkIdentity existingIdentity)) { diff --git a/Assets/Mirror/Runtime/NetworkServer.cs b/Assets/Mirror/Runtime/NetworkServer.cs index c909105a2..2ad9385cb 100644 --- a/Assets/Mirror/Runtime/NetworkServer.cs +++ b/Assets/Mirror/Runtime/NetworkServer.cs @@ -1140,24 +1140,6 @@ public static void Spawn(GameObject obj, Guid assetId, NetworkConnection ownerCo SpawnObject(obj, ownerConnection); } - // TODO merge with ConsiderForSpawning on client - internal static bool IsSceneObject(NetworkIdentity identity) - { - if (identity.gameObject.hideFlags == HideFlags.NotEditable || - identity.gameObject.hideFlags == HideFlags.HideAndDontSave) - return false; - -#if UNITY_EDITOR - // this never seems to trigger. - // even if a prefab is dragged into the scene. - if (UnityEditor.EditorUtility.IsPersistent(identity.gameObject)) - return false; -#endif - - // If not a scene object - return identity.sceneId != 0; - } - /// Spawns NetworkIdentities in the scene on the server. // NetworkIdentity objects in a scene are disabled by default. Calling // SpawnObjects() causes these scene objects to be enabled and spawned. @@ -1173,7 +1155,7 @@ public static bool SpawnObjects() // first pass: activate all scene objects foreach (NetworkIdentity identity in identities) { - if (IsSceneObject(identity)) + if (Utils.IsSceneObject(identity)) { // Debug.Log($"SpawnObjects sceneId:{identity.sceneId:X} name:{identity.gameObject.name}"); identity.gameObject.SetActive(true); @@ -1193,7 +1175,7 @@ public static bool SpawnObjects() // second pass: spawn all scene objects foreach (NetworkIdentity identity in identities) { - if (IsSceneObject(identity)) + if (Utils.IsSceneObject(identity)) // pass connection so that authority is not lost when server loads a scene // https://github.com/vis2k/Mirror/pull/2987 Spawn(identity.gameObject, identity.connectionToClient); diff --git a/Assets/Mirror/Runtime/Utils.cs b/Assets/Mirror/Runtime/Utils.cs index d39ed98fc..570a45ef4 100644 --- a/Assets/Mirror/Runtime/Utils.cs +++ b/Assets/Mirror/Runtime/Utils.cs @@ -51,6 +51,22 @@ public static bool IsPrefab(GameObject obj) #endif } + // simplified IsSceneObject check from Mirror II + public static bool IsSceneObject(NetworkIdentity identity) + { + // original UNET / Mirror still had the IsPersistent check. + // it never fires though. even for Prefabs dragged to the Scene. + // (see Scene Objects example scene.) + // #if UNITY_EDITOR + // if (UnityEditor.EditorUtility.IsPersistent(identity.gameObject)) + // return false; + // #endif + + return identity.gameObject.hideFlags != HideFlags.NotEditable && + identity.gameObject.hideFlags != HideFlags.HideAndDontSave && + identity.sceneId != 0; + } + public static bool IsSceneObjectWithPrefabParent(GameObject gameObject, out GameObject prefab) { prefab = null; diff --git a/Assets/Mirror/Tests/Editor/NetworkServerTest.cs b/Assets/Mirror/Tests/Editor/NetworkServerTest.cs index ba2bdeaf1..83119a976 100644 --- a/Assets/Mirror/Tests/Editor/NetworkServerTest.cs +++ b/Assets/Mirror/Tests/Editor/NetworkServerTest.cs @@ -1032,18 +1032,18 @@ public void IsSceneObject() identity.sceneId = 42; // should be valid as long as it has a sceneId - Assert.That(NetworkServer.IsSceneObject(identity), Is.True); + Assert.That(Utils.IsSceneObject(identity), Is.True); // shouldn't be valid with 0 sceneID identity.sceneId = 0; - Assert.That(NetworkServer.IsSceneObject(identity), Is.False); + Assert.That(Utils.IsSceneObject(identity), Is.False); identity.sceneId = 42; // shouldn't be valid for certain hide flags go.hideFlags = HideFlags.NotEditable; - Assert.That(NetworkServer.IsSceneObject(identity), Is.False); + Assert.That(Utils.IsSceneObject(identity), Is.False); go.hideFlags = HideFlags.HideAndDontSave; - Assert.That(NetworkServer.IsSceneObject(identity), Is.False); + Assert.That(Utils.IsSceneObject(identity), Is.False); } [Test]