From bfa8a8677bd19b636aaf6898272b69d513341a39 Mon Sep 17 00:00:00 2001 From: Robin Rolf Date: Sat, 11 Feb 2023 16:03:46 +0000 Subject: [PATCH 1/2] feat: InterestManagementBase A interest management base class that allows more advanced interest management by bypassing the built-in HashSet checks via Rebuild overriding --- Assets/Mirror/Core/InterestManagement.cs | 57 +------------ Assets/Mirror/Core/InterestManagementBase.cs | 83 +++++++++++++++++++ .../Core/InterestManagementBase.cs.meta | 3 + Assets/Mirror/Core/NetworkClient.cs | 2 +- Assets/Mirror/Core/NetworkServer.cs | 2 +- 5 files changed, 90 insertions(+), 57 deletions(-) create mode 100644 Assets/Mirror/Core/InterestManagementBase.cs create mode 100644 Assets/Mirror/Core/InterestManagementBase.cs.meta diff --git a/Assets/Mirror/Core/InterestManagement.cs b/Assets/Mirror/Core/InterestManagement.cs index d18db34e1a0..217e73caf55 100644 --- a/Assets/Mirror/Core/InterestManagement.cs +++ b/Assets/Mirror/Core/InterestManagement.cs @@ -8,40 +8,12 @@ namespace Mirror { [DisallowMultipleComponent] [HelpURL("https://mirror-networking.gitbook.io/docs/guides/interest-management")] - public abstract class InterestManagement : MonoBehaviour + public abstract class InterestManagement : InterestManagementBase { // allocate newObservers helper HashSet readonly HashSet newObservers = new HashSet(); - // Awake configures InterestManagement in NetworkServer/Client - // Do NOT check for active server or client here. - // Awake must always set the static aoi references. - // make sure to call base.Awake when overwriting! - protected virtual void Awake() - { - if (NetworkServer.aoi == null) - { - NetworkServer.aoi = this; - } - else Debug.LogError($"Only one InterestManagement component allowed. {NetworkServer.aoi.GetType()} has been set up already."); - - if (NetworkClient.aoi == null) - { - NetworkClient.aoi = this; - } - else Debug.LogError($"Only one InterestManagement component allowed. {NetworkClient.aoi.GetType()} has been set up already."); - } - - [ServerCallback] - public virtual void Reset() {} - - // Callback used by the visibility system to determine if an observer - // (player) can see the NetworkIdentity. If this function returns true, - // the network connection will be added as an observer. - // conn: Network connection of a player. - // returns True if the player can see this object. - public abstract bool OnCheckObserver(NetworkIdentity identity, NetworkConnectionToClient newObserver); // rebuild observers for the given NetworkIdentity. // Server will automatically spawn/despawn added/removed ones. @@ -77,32 +49,7 @@ protected void RebuildAll() } } - // Callback used by the visibility system for objects on a host. - // Objects on a host (with a local client) cannot be disabled or - // destroyed when they are not visible to the local client. So this - // function is called to allow custom code to hide these objects. A - // typical implementation will disable renderer components on the - // object. This is only called on local clients on a host. - // => need the function in here and virtual so people can overwrite! - // => not everyone wants to hide renderers! - [ServerCallback] - public virtual void SetHostVisibility(NetworkIdentity identity, bool visible) - { - foreach (Renderer rend in identity.GetComponentsInChildren()) - rend.enabled = visible; - } - - /// Called on the server when a new networked object is spawned. - // (useful for 'only rebuild if changed' interest management algorithms) - [ServerCallback] - public virtual void OnSpawned(NetworkIdentity identity) {} - - /// Called on the server when a networked object is destroyed. - // (useful for 'only rebuild if changed' interest management algorithms) - [ServerCallback] - public virtual void OnDestroyed(NetworkIdentity identity) {} - - public void Rebuild(NetworkIdentity identity, bool initialize) + public override void Rebuild(NetworkIdentity identity, bool initialize) { // clear newObservers hashset before using it newObservers.Clear(); diff --git a/Assets/Mirror/Core/InterestManagementBase.cs b/Assets/Mirror/Core/InterestManagementBase.cs new file mode 100644 index 00000000000..a7535f7fab7 --- /dev/null +++ b/Assets/Mirror/Core/InterestManagementBase.cs @@ -0,0 +1,83 @@ +// interest management component for custom solutions like +// distance based, spatial hashing, raycast based, etc. +using System.Collections.Generic; +using UnityEngine; + +namespace Mirror +{ + [DisallowMultipleComponent] + [HelpURL("https://mirror-networking.gitbook.io/docs/guides/interest-management")] + public abstract class InterestManagementBase : MonoBehaviour + { + // Awake configures InterestManagementBase in NetworkServer/Client + // Do NOT check for active server or client here. + // Awake must always set the static aoi references. + // make sure to call base.Awake when overwriting! + protected virtual void Awake() + { + if (NetworkServer.aoi == null) + { + NetworkServer.aoi = this; + } + else Debug.LogError($"Only one InterestManagement component allowed. {NetworkServer.aoi.GetType()} has been set up already."); + + if (NetworkClient.aoi == null) + { + NetworkClient.aoi = this; + } + else Debug.LogError($"Only one InterestManagement component allowed. {NetworkClient.aoi.GetType()} has been set up already."); + } + + [ServerCallback] + public virtual void Reset() {} + + // Callback used by the visibility system to determine if an observer + // (player) can see the NetworkIdentity. If this function returns true, + // the network connection will be added as an observer. + // conn: Network connection of a player. + // returns True if the player can see this object. + public abstract bool OnCheckObserver(NetworkIdentity identity, NetworkConnectionToClient newObserver); + + + // Callback used by the visibility system for objects on a host. + // Objects on a host (with a local client) cannot be disabled or + // destroyed when they are not visible to the local client. So this + // function is called to allow custom code to hide these objects. A + // typical implementation will disable renderer components on the + // object. This is only called on local clients on a host. + // => need the function in here and virtual so people can overwrite! + // => not everyone wants to hide renderers! + [ServerCallback] + public virtual void SetHostVisibility(NetworkIdentity identity, bool visible) + { + foreach (Renderer rend in identity.GetComponentsInChildren()) + rend.enabled = visible; + } + + /// Called on the server when a new networked object is spawned. + // (useful for 'only rebuild if changed' interest management algorithms) + [ServerCallback] + public virtual void OnSpawned(NetworkIdentity identity) {} + + /// Called on the server when a networked object is destroyed. + // (useful for 'only rebuild if changed' interest management algorithms) + [ServerCallback] + public virtual void OnDestroyed(NetworkIdentity identity) {} + + public abstract void Rebuild(NetworkIdentity identity, bool initialize); + + /// Adds the specified connection to the observers of identity + protected void AddObserver(NetworkConnectionToClient connection, NetworkIdentity identity) + { + connection.AddToObserving(identity); + identity.observers.Add(connection.connectionId, connection); + } + + /// Removes the specified connection from the observers of identity + protected void RemoveObserver(NetworkConnectionToClient connection, NetworkIdentity identity) + { + connection.RemoveFromObserving(identity, false); + identity.observers.Remove(connection.connectionId); + } + } +} diff --git a/Assets/Mirror/Core/InterestManagementBase.cs.meta b/Assets/Mirror/Core/InterestManagementBase.cs.meta new file mode 100644 index 00000000000..526e1192a83 --- /dev/null +++ b/Assets/Mirror/Core/InterestManagementBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 18bd2ffe65a444f3b13d59bdac7f2228 +timeCreated: 1676129329 \ No newline at end of file diff --git a/Assets/Mirror/Core/NetworkClient.cs b/Assets/Mirror/Core/NetworkClient.cs index c0b76a1fd94..06cd81cb9fe 100644 --- a/Assets/Mirror/Core/NetworkClient.cs +++ b/Assets/Mirror/Core/NetworkClient.cs @@ -115,7 +115,7 @@ public static partial class NetworkClient // interest management component (optional) // only needed for SetHostVisibility - public static InterestManagement aoi; + public static InterestManagementBase aoi; // scene loading public static bool isLoadingScene; diff --git a/Assets/Mirror/Core/NetworkServer.cs b/Assets/Mirror/Core/NetworkServer.cs index 39d60b062b6..f6388931ca2 100644 --- a/Assets/Mirror/Core/NetworkServer.cs +++ b/Assets/Mirror/Core/NetworkServer.cs @@ -68,7 +68,7 @@ public static partial class NetworkServer // interest management component (optional) // by default, everyone observes everyone - public static InterestManagement aoi; + public static InterestManagementBase aoi; // OnConnected / OnDisconnected used to be NetworkMessages that were // invoked. this introduced a bug where external clients could send From 161b8924c18a3793550c22a05790a6dbc442f0ca Mon Sep 17 00:00:00 2001 From: mischa <16416509+vis2k@users.noreply.github.com> Date: Thu, 16 Feb 2023 12:57:10 +0100 Subject: [PATCH 2/2] Update Assets/Mirror/Core/InterestManagementBase.cs --- Assets/Mirror/Core/InterestManagementBase.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Assets/Mirror/Core/InterestManagementBase.cs b/Assets/Mirror/Core/InterestManagementBase.cs index a7535f7fab7..ab89107ea22 100644 --- a/Assets/Mirror/Core/InterestManagementBase.cs +++ b/Assets/Mirror/Core/InterestManagementBase.cs @@ -1,5 +1,6 @@ // interest management component for custom solutions like // distance based, spatial hashing, raycast based, etc. +// low level base class allows for low level spatial hashing etc., which is 3-5x faster. using System.Collections.Generic; using UnityEngine;