From 99db407990c68909610b42af0444510c32d2e5b7 Mon Sep 17 00:00:00 2001 From: Robin Rolf Date: Wed, 14 Jul 2021 05:01:43 +0200 Subject: [PATCH] feat: SceneInterestManagement (#2762) * feat: Add OnSpawned/OnDestroyed events to interest management * feat: SceneInterestManagement --- .../Components/InterestManagement/Scene.meta | 3 + .../Scene/SceneInterestManagement.cs | 104 ++++++++++++++++++ .../Scene/SceneInterestManagement.cs.meta | 11 ++ .../Prefabs/Icosphere.prefab | 18 +-- .../Prefabs/Player.prefab | 18 +-- .../Prefabs/Prize.prefab | 19 +--- .../MultipleAdditiveScenes/Scenes/Game.unity | 12 +- .../MultipleAdditiveScenes/Scenes/Main.unity | 16 ++- 8 files changed, 147 insertions(+), 54 deletions(-) create mode 100644 Assets/Mirror/Components/InterestManagement/Scene.meta create mode 100644 Assets/Mirror/Components/InterestManagement/Scene/SceneInterestManagement.cs create mode 100644 Assets/Mirror/Components/InterestManagement/Scene/SceneInterestManagement.cs.meta diff --git a/Assets/Mirror/Components/InterestManagement/Scene.meta b/Assets/Mirror/Components/InterestManagement/Scene.meta new file mode 100644 index 000000000..28b469fe3 --- /dev/null +++ b/Assets/Mirror/Components/InterestManagement/Scene.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7655d309a46a4bd4860edf964228b3f6 +timeCreated: 1622649517 \ No newline at end of file diff --git a/Assets/Mirror/Components/InterestManagement/Scene/SceneInterestManagement.cs b/Assets/Mirror/Components/InterestManagement/Scene/SceneInterestManagement.cs new file mode 100644 index 000000000..87311d69e --- /dev/null +++ b/Assets/Mirror/Components/InterestManagement/Scene/SceneInterestManagement.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using UnityEngine.SceneManagement; + +namespace Mirror +{ + public class SceneInterestManagement : InterestManagement + { + // Use Scene instead of string scene.name because when additively loading multiples of a subscene the name won't be unique + private readonly Dictionary> sceneObjects = + new Dictionary>(); + private readonly Dictionary lastObjectScene = new Dictionary(); + + private HashSet dirtyScenes = new HashSet(); + + public override void OnSpawned(NetworkIdentity identity) + { + Scene currentScene = gameObject.scene; + lastObjectScene[identity] = currentScene; + // Debug.Log($"SceneInterestManagement.OnSpawned({gameObject.name}) currentScene: {currentScene}"); + if (!sceneObjects.TryGetValue(currentScene, out HashSet objects)) + { + objects = new HashSet(); + sceneObjects.Add(currentScene, objects); + } + + objects.Add(identity); + } + + public override void OnDestroyed(NetworkIdentity identity) + { + Scene currentScene = lastObjectScene[identity]; + lastObjectScene.Remove(identity); + if (sceneObjects.TryGetValue(currentScene, out HashSet objects) && objects.Remove(identity)) + RebuildSceneObservers(currentScene); + } + + void Update() + { + // only on server + if (!NetworkServer.active) return; + + foreach (var netIdentity in NetworkIdentity.spawned.Values) + { + + Scene currentScene = lastObjectScene[netIdentity]; + Scene newScene = netIdentity.gameObject.scene; + if (newScene == currentScene) continue; + + // Mark new/old scenes as dirty so they get rebuilt + dirtyScenes.Add(currentScene); + dirtyScenes.Add(newScene); + + // This object is in a new scene so observers in the prior scene + // and the new scene need to rebuild their respective observers lists. + + // Remove this object from the hashset of the scene it just left + sceneObjects[currentScene].Remove(netIdentity); + + // Set this to the new scene this object just entered + lastObjectScene[netIdentity] = newScene; + + // Make sure this new scene is in the dictionary + if (!sceneObjects.ContainsKey(newScene)) + sceneObjects.Add(newScene, new HashSet()); + + // Add this object to the hashset of the new scene + sceneObjects[newScene].Add(netIdentity); + } + + foreach (Scene dirtyScene in dirtyScenes) + { + RebuildSceneObservers(dirtyScene); + } + + dirtyScenes.Clear(); + } + + void RebuildSceneObservers(Scene scene) + { + foreach (NetworkIdentity netIdentity in sceneObjects[scene]) + if (netIdentity != null) + NetworkServer.RebuildObservers(netIdentity, false); + } + + public override bool OnCheckObserver(NetworkIdentity identity, NetworkConnection newObserver) + { + return identity.gameObject.scene == gameObject.scene; + } + + public override void OnRebuildObservers(NetworkIdentity identity, HashSet newObservers, + bool initialize) + { + if (!sceneObjects.TryGetValue(identity.gameObject.scene, out HashSet objects)) + { + return; + } + + // Add everything in the hashset for this object's current scene + foreach (NetworkIdentity networkIdentity in objects) + if (networkIdentity != null && networkIdentity.connectionToClient != null) + newObservers.Add(networkIdentity.connectionToClient); + } + } +} diff --git a/Assets/Mirror/Components/InterestManagement/Scene/SceneInterestManagement.cs.meta b/Assets/Mirror/Components/InterestManagement/Scene/SceneInterestManagement.cs.meta new file mode 100644 index 000000000..9cc1ff50a --- /dev/null +++ b/Assets/Mirror/Components/InterestManagement/Scene/SceneInterestManagement.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b979f26c95d34324ba005bfacfa9c4fc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 7453abfe9e8b2c04a8a47eb536fe21eb, type: 3} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Icosphere.prefab b/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Icosphere.prefab index e2dc34ba7..16b861d37 100644 --- a/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Icosphere.prefab +++ b/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Icosphere.prefab @@ -105,7 +105,6 @@ GameObject: - component: {fileID: 5513112217680897778} - component: {fileID: -7012348765844800875} - component: {fileID: -5073764247860119520} - - component: {fileID: -8786580539857106334} - component: {fileID: 8774992865005872063} - component: {fileID: -73998256042230442} - component: {fileID: -2850352209440038129} @@ -168,22 +167,9 @@ MonoBehaviour: localScaleSensitivity: 0.01 compressRotation: 0 interpolateScale: 0 + interpolateRotation: 1 + interpolatePosition: 1 syncScale: 0 ---- !u!114 &-8786580539857106334 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5513112217680870098} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: b7fdb599e1359924bad6255660370252, type: 3} - m_Name: - m_EditorClassIdentifier: - syncMode: 0 - syncInterval: 0.1 - forceHidden: 0 --- !u!114 &8774992865005872063 MonoBehaviour: m_ObjectHideFlags: 0 diff --git a/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Player.prefab b/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Player.prefab index 2e8264344..565f2546b 100644 --- a/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Player.prefab +++ b/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Player.prefab @@ -89,7 +89,6 @@ GameObject: m_Component: - component: {fileID: 4822224316094678} - component: {fileID: 114402732107420660} - - component: {fileID: 114720308987319626} - component: {fileID: 114265392388239132} - component: {fileID: 143011667059871024} - component: {fileID: 4839740653866577337} @@ -136,21 +135,6 @@ MonoBehaviour: visible: 0 m_AssetId: hasSpawned: 0 ---- !u!114 &114720308987319626 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1480027675339556} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: b7fdb599e1359924bad6255660370252, type: 3} - m_Name: - m_EditorClassIdentifier: - syncMode: 0 - syncInterval: 0.1 - forceHidden: 0 --- !u!114 &114265392388239132 MonoBehaviour: m_ObjectHideFlags: 0 @@ -171,6 +155,8 @@ MonoBehaviour: localScaleSensitivity: 0.01 compressRotation: 0 interpolateScale: 0 + interpolateRotation: 1 + interpolatePosition: 1 syncScale: 0 --- !u!143 &143011667059871024 CharacterController: diff --git a/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Prize.prefab b/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Prize.prefab index c09f4aa79..c08171fae 100644 --- a/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Prize.prefab +++ b/Assets/Mirror/Examples/MultipleAdditiveScenes/Prefabs/Prize.prefab @@ -12,7 +12,6 @@ GameObject: - component: {fileID: 135606878775227198} - component: {fileID: 6909319328281960030} - component: {fileID: 114251241889735402} - - component: {fileID: 114426876133629542} - component: {fileID: 114048121767222990} - component: {fileID: 7669440687796875101} m_Layer: 0 @@ -80,23 +79,9 @@ MonoBehaviour: m_EditorClassIdentifier: sceneId: 0 serverOnly: 0 + visible: 0 m_AssetId: hasSpawned: 0 ---- !u!114 &114426876133629542 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1139254171913846} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: b7fdb599e1359924bad6255660370252, type: 3} - m_Name: - m_EditorClassIdentifier: - syncMode: 0 - syncInterval: 0.1 - forceHidden: 0 --- !u!114 &114048121767222990 MonoBehaviour: m_ObjectHideFlags: 0 @@ -112,7 +97,6 @@ MonoBehaviour: syncMode: 0 syncInterval: 0.1 available: 1 - spawner: {fileID: 0} randomColor: {fileID: 7669440687796875101} --- !u!114 &7669440687796875101 MonoBehaviour: @@ -185,6 +169,7 @@ MeshRenderer: m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 m_RenderingLayerMask: 1 m_RendererPriority: 0 m_Materials: diff --git a/Assets/Mirror/Examples/MultipleAdditiveScenes/Scenes/Game.unity b/Assets/Mirror/Examples/MultipleAdditiveScenes/Scenes/Game.unity index bfc438483..7227de4f1 100644 --- a/Assets/Mirror/Examples/MultipleAdditiveScenes/Scenes/Game.unity +++ b/Assets/Mirror/Examples/MultipleAdditiveScenes/Scenes/Game.unity @@ -243,7 +243,8 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - m_RemovedComponents: [] + m_RemovedComponents: + - {fileID: -8786580539857106334, guid: a104de86221e66a48832c222471d4f1e, type: 3} m_SourcePrefab: {fileID: 100100000, guid: a104de86221e66a48832c222471d4f1e, type: 3} --- !u!4 &535961556 stripped Transform: @@ -338,7 +339,8 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - m_RemovedComponents: [] + m_RemovedComponents: + - {fileID: -8786580539857106334, guid: a104de86221e66a48832c222471d4f1e, type: 3} m_SourcePrefab: {fileID: 100100000, guid: a104de86221e66a48832c222471d4f1e, type: 3} --- !u!4 &1069065321 stripped Transform: @@ -433,7 +435,8 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - m_RemovedComponents: [] + m_RemovedComponents: + - {fileID: -8786580539857106334, guid: a104de86221e66a48832c222471d4f1e, type: 3} m_SourcePrefab: {fileID: 100100000, guid: a104de86221e66a48832c222471d4f1e, type: 3} --- !u!4 &1072549450 stripped Transform: @@ -721,7 +724,8 @@ PrefabInstance: propertyPath: m_LocalEulerAnglesHint.z value: 0 objectReference: {fileID: 0} - m_RemovedComponents: [] + m_RemovedComponents: + - {fileID: -8786580539857106334, guid: a104de86221e66a48832c222471d4f1e, type: 3} m_SourcePrefab: {fileID: 100100000, guid: a104de86221e66a48832c222471d4f1e, type: 3} --- !u!4 &2061474489 stripped Transform: diff --git a/Assets/Mirror/Examples/MultipleAdditiveScenes/Scenes/Main.unity b/Assets/Mirror/Examples/MultipleAdditiveScenes/Scenes/Main.unity index b34c652cf..a3a46ab9c 100644 --- a/Assets/Mirror/Examples/MultipleAdditiveScenes/Scenes/Main.unity +++ b/Assets/Mirror/Examples/MultipleAdditiveScenes/Scenes/Main.unity @@ -38,7 +38,7 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 690741348} - m_IndirectSpecularColor: {r: 0.17276844, g: 0.21589246, b: 0.2978263, a: 1} + m_IndirectSpecularColor: {r: 0.4366757, g: 0.48427194, b: 0.5645252, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: @@ -216,6 +216,7 @@ GameObject: - component: {fileID: 69965669} - component: {fileID: 69965667} - component: {fileID: 69965671} + - component: {fileID: 69965668} m_Layer: 0 m_Name: Network m_TagString: Untagged @@ -238,6 +239,18 @@ MonoBehaviour: showGUI: 1 offsetX: 0 offsetY: 0 +--- !u!114 &69965668 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 69965666} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b979f26c95d34324ba005bfacfa9c4fc, type: 3} + m_Name: + m_EditorClassIdentifier: --- !u!114 &69965669 MonoBehaviour: m_ObjectHideFlags: 0 @@ -304,6 +317,7 @@ MonoBehaviour: Port: 7777 NoDelay: 1 Interval: 10 + Timeout: 10000 FastResend: 2 CongestionWindow: 0 SendWindowSize: 4096