diff --git a/Assets/Mirror/Components/NetworkSceneChecker.cs b/Assets/Mirror/Components/NetworkSceneChecker.cs index 7f412fd20ac..7e729e34cc7 100644 --- a/Assets/Mirror/Components/NetworkSceneChecker.cs +++ b/Assets/Mirror/Components/NetworkSceneChecker.cs @@ -31,9 +31,11 @@ void Awake() { currentScene = gameObject.scene; if (LogFilter.Debug) Debug.Log($"NetworkSceneChecker.Awake currentScene: {currentScene}"); + + netIdentity.OnStartServer.AddListener(OnStartServer); } - public override void OnStartServer() + public void OnStartServer() { if (!sceneCheckerObjects.ContainsKey(currentScene)) sceneCheckerObjects.Add(currentScene, new HashSet()); diff --git a/Assets/Mirror/Examples/AdditiveScenes/Scripts/PlayerController.cs b/Assets/Mirror/Examples/AdditiveScenes/Scripts/PlayerController.cs index 53d6ddb4724..67492648477 100644 --- a/Assets/Mirror/Examples/AdditiveScenes/Scripts/PlayerController.cs +++ b/Assets/Mirror/Examples/AdditiveScenes/Scripts/PlayerController.cs @@ -8,16 +8,19 @@ public class PlayerController : NetworkBehaviour { public CharacterController characterController; + void Awake() + { + netIdentity.OnStartLocalPlayer.AddListener(OnStartLocalPlayer); + } + void OnValidate() { if (characterController == null) characterController = GetComponent(); } - public override void OnStartLocalPlayer() + public void OnStartLocalPlayer() { - base.OnStartLocalPlayer(); - Camera.main.orthographic = false; Camera.main.transform.SetParent(transform); Camera.main.transform.localPosition = new Vector3(0f, 3f, -8f); diff --git a/Assets/Mirror/Examples/AdditiveScenes/Scripts/RandomColor.cs b/Assets/Mirror/Examples/AdditiveScenes/Scripts/RandomColor.cs index f7023df72d0..02a3d076b55 100644 --- a/Assets/Mirror/Examples/AdditiveScenes/Scripts/RandomColor.cs +++ b/Assets/Mirror/Examples/AdditiveScenes/Scripts/RandomColor.cs @@ -4,9 +4,13 @@ namespace Mirror.Examples.Additive { public class RandomColor : NetworkBehaviour { - public override void OnStartServer() + void Awake() + { + netIdentity.OnStartServer.AddListener(OnStartServer); + } + + public void OnStartServer() { - base.OnStartServer(); color = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f); } diff --git a/Assets/Mirror/Examples/Basic/Scripts/Player.cs b/Assets/Mirror/Examples/Basic/Scripts/Player.cs index 68eaa3f02cc..bc30f9db918 100644 --- a/Assets/Mirror/Examples/Basic/Scripts/Player.cs +++ b/Assets/Mirror/Examples/Basic/Scripts/Player.cs @@ -23,6 +23,13 @@ public class Player : NetworkBehaviour [SyncVar(hook = nameof(OnPlayerDataChanged))] public int playerData; + void Awake() + { + netIdentity.OnStartServer.AddListener(OnStartServer); + netIdentity.OnStartClient.AddListener(OnStartClient); + netIdentity.OnStartLocalPlayer.AddListener(OnStartLocalPlayer); + } + // This is called by the hook of playerData SyncVar above void OnPlayerDataChanged(int oldPlayerData, int newPlayerData) { @@ -31,10 +38,8 @@ void OnPlayerDataChanged(int oldPlayerData, int newPlayerData) } // This fires on server when this player object is network-ready - public override void OnStartServer() + public void OnStartServer() { - base.OnStartServer(); - // Set SyncVar values playerNo = connectionToClient.connectionId; playerColor = Random.ColorHSV(0f, 1f, 0.9f, 0.9f, 1f, 1f); @@ -51,10 +56,8 @@ void UpdateData() } // This fires on all clients when this player object is network-ready - public override void OnStartClient() + public void OnStartClient() { - base.OnStartClient(); - // Make this a child of the layout panel in the Canvas transform.SetParent(GameObject.Find("PlayersPanel").transform); @@ -69,10 +72,8 @@ public override void OnStartClient() } // This only fires on the local client when this player object is network-ready - public override void OnStartLocalPlayer() + public void OnStartLocalPlayer() { - base.OnStartLocalPlayer(); - // apply a shaded background to our player image.color = new Color(1f, 1f, 1f, 0.1f); } diff --git a/Assets/Mirror/Examples/Pong/Scripts/Ball.cs b/Assets/Mirror/Examples/Pong/Scripts/Ball.cs index 50515adfebe..647c1d12d38 100644 --- a/Assets/Mirror/Examples/Pong/Scripts/Ball.cs +++ b/Assets/Mirror/Examples/Pong/Scripts/Ball.cs @@ -7,10 +7,13 @@ public class Ball : NetworkBehaviour public float speed = 30; public Rigidbody2D rigidbody2d; - public override void OnStartServer() + void Awake() { - base.OnStartServer(); + netIdentity.OnStartServer.AddListener(OnStartServer); + } + public void OnStartServer() + { // only simulate ball physics on server rigidbody2d.simulated = true; diff --git a/Assets/Mirror/Examples/Room/Scripts/NetworkRoomPlayerExt.cs b/Assets/Mirror/Examples/Room/Scripts/NetworkRoomPlayerExt.cs index aa981ce1606..8a544cc9e4a 100644 --- a/Assets/Mirror/Examples/Room/Scripts/NetworkRoomPlayerExt.cs +++ b/Assets/Mirror/Examples/Room/Scripts/NetworkRoomPlayerExt.cs @@ -6,11 +6,14 @@ namespace Mirror.Examples.NetworkRoom [AddComponentMenu("")] public class NetworkRoomPlayerExt : NetworkRoomPlayer { - public override void OnStartClient() + void Awake() { - if (LogFilter.Debug) Debug.LogFormat("OnStartClient {0}", SceneManager.GetActiveScene().name); + netIdentity.OnStartClient.AddListener(OnStartClient); + } - base.OnStartClient(); + public void OnStartClient() + { + if (LogFilter.Debug) Debug.LogFormat("OnStartClient {0}", SceneManager.GetActiveScene().name); } public override void OnClientEnterRoom() diff --git a/Assets/Mirror/Examples/Room/Scripts/PlayerController.cs b/Assets/Mirror/Examples/Room/Scripts/PlayerController.cs index e33a12a75a8..1fd6dca9bd6 100644 --- a/Assets/Mirror/Examples/Room/Scripts/PlayerController.cs +++ b/Assets/Mirror/Examples/Room/Scripts/PlayerController.cs @@ -8,16 +8,19 @@ public class PlayerController : NetworkBehaviour { public CharacterController characterController; + void Awake() + { + netIdentity.OnStartLocalPlayer.AddListener(OnStartLocalPlayer); + } + void OnValidate() { if (characterController == null) characterController = GetComponent(); } - public override void OnStartLocalPlayer() + public void OnStartLocalPlayer() { - base.OnStartLocalPlayer(); - Camera.main.orthographic = false; Camera.main.transform.SetParent(transform); Camera.main.transform.localPosition = new Vector3(0f, 3f, -8f); diff --git a/Assets/Mirror/Examples/Room/Scripts/RandomColor.cs b/Assets/Mirror/Examples/Room/Scripts/RandomColor.cs index 6092deb533c..9ac0d186ee7 100644 --- a/Assets/Mirror/Examples/Room/Scripts/RandomColor.cs +++ b/Assets/Mirror/Examples/Room/Scripts/RandomColor.cs @@ -4,9 +4,13 @@ namespace Mirror.Examples.NetworkRoom { public class RandomColor : NetworkBehaviour { - public override void OnStartServer() + void Awake() + { + netIdentity.OnStartServer.AddListener(OnStartServer); + } + + public void OnStartServer() { - base.OnStartServer(); color = Random.ColorHSV(0f, 1f, 1f, 1f, 0.5f, 1f); } diff --git a/Assets/Mirror/Examples/Room/Scripts/Spawner.cs b/Assets/Mirror/Examples/Room/Scripts/Spawner.cs index 09bc32226de..f5a49b7b0eb 100644 --- a/Assets/Mirror/Examples/Room/Scripts/Spawner.cs +++ b/Assets/Mirror/Examples/Room/Scripts/Spawner.cs @@ -6,7 +6,12 @@ public class Spawner : NetworkBehaviour { public NetworkIdentity prizePrefab; - public override void OnStartServer() + void Awake() + { + netIdentity.OnStartServer.AddListener(OnStartServer); + } + + public void OnStartServer() { for (int i = 0; i < 10; i++) SpawnPrize(); diff --git a/Assets/Mirror/Examples/Tanks/Scripts/Projectile.cs b/Assets/Mirror/Examples/Tanks/Scripts/Projectile.cs index 993fa7e0be0..a7bd26a20f0 100644 --- a/Assets/Mirror/Examples/Tanks/Scripts/Projectile.cs +++ b/Assets/Mirror/Examples/Tanks/Scripts/Projectile.cs @@ -8,7 +8,12 @@ public class Projectile : NetworkBehaviour public Rigidbody rigidBody; public float force = 1000; - public override void OnStartServer() + void Awake() + { + netIdentity.OnStartServer.AddListener(OnStartServer); + } + + public void OnStartServer() { Invoke(nameof(DestroySelf), destroyAfter); } diff --git a/Assets/Mirror/Runtime/NetworkBehaviour.cs b/Assets/Mirror/Runtime/NetworkBehaviour.cs index d7b43d5173d..93e991fc723 100644 --- a/Assets/Mirror/Runtime/NetworkBehaviour.cs +++ b/Assets/Mirror/Runtime/NetworkBehaviour.cs @@ -796,46 +796,6 @@ internal void DeSerializeObjectsDelta(NetworkReader reader) } } - /// - /// This is invoked on clients when the server has caused this object to be destroyed. - /// This can be used as a hook to invoke effects or do client specific cleanup. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - ///Called on clients when the server destroys the GameObject. - public virtual void OnNetworkDestroy() { } - - /// - /// This is invoked for NetworkBehaviour objects when they become active on the server. - /// This could be triggered by NetworkServer.Listen() for objects in the scene, or by NetworkServer.Spawn() for objects that are dynamically created. - /// This will be called for objects on a "host" as well as for object on a dedicated server. - /// - public virtual void OnStartServer() { } - - /// - /// Called on every NetworkBehaviour when it is activated on a client. - /// Objects on the host have this function called, as there is a local client on the host. The values of SyncVars on object are guaranteed to be initialized correctly with the latest state from the server when this function is called on the client. - /// - public virtual void OnStartClient() { } - - /// - /// Called when the local player object has been set up. - /// This happens after OnStartClient(), as it is triggered by an ownership message from the server. This is an appropriate place to activate components or functionality that should only be active for the local player, such as cameras and input. - /// - public virtual void OnStartLocalPlayer() { } - - /// - /// This is invoked on behaviours that have authority, based on context and NetworkIdentity.hasAuthority. - /// This is called after OnStartServer and before OnStartClient. - /// When is called on the server, this will be called on the client that owns the object. When an object is spawned with NetworkServer.Spawn with a NetworkConnection parameter included, this will be called on the client that owns the object. - /// - public virtual void OnStartAuthority() { } - - /// - /// This is invoked on behaviours when authority is removed. - /// When NetworkIdentity.RemoveClientAuthority is called on the server, this will be called on the client that owns the object. - /// - public virtual void OnStopAuthority() { } - /// /// Callback used by the visibility system to (re)construct the set of observers that can see this object. /// Implementations of this callback should add network connections of players that can see this object to the observers set. diff --git a/Assets/Mirror/Runtime/NetworkClient.cs b/Assets/Mirror/Runtime/NetworkClient.cs index 7b7a0331012..09973db8c0e 100644 --- a/Assets/Mirror/Runtime/NetworkClient.cs +++ b/Assets/Mirror/Runtime/NetworkClient.cs @@ -819,7 +819,7 @@ void UnSpawn(NetworkIdentity identity) { Guid assetId = identity.assetId; - identity.OnNetworkDestroy(); + identity.NetworkDestroy(); if (unspawnHandlers.TryGetValue(assetId, out UnSpawnDelegate handler) && handler != null) { handler(identity.gameObject); @@ -892,7 +892,7 @@ void ApplySpawnPayload(NetworkIdentity identity, SpawnMessage msg) if (isSpawnFinished) { identity.NotifyAuthority(); - identity.OnStartClient(); + identity.StartClient(); CheckForLocalPlayer(identity); } } @@ -992,7 +992,7 @@ internal void OnObjectSpawnFinished(ObjectSpawnFinishedMessage _) foreach (NetworkIdentity identity in Spawned.Values.OrderBy(uv => uv.netId)) { identity.NotifyAuthority(); - identity.OnStartClient(); + identity.StartClient(); CheckForLocalPlayer(identity); } isSpawnFinished = true; @@ -1049,7 +1049,7 @@ internal void OnHostClientSpawn(SpawnMessage msg) localObject.hasAuthority = msg.isOwner; localObject.NotifyAuthority(); - localObject.OnStartClient(); + localObject.StartClient(); localObject.OnSetHostVisibility(true); CheckForLocalPlayer(localObject); } @@ -1102,7 +1102,7 @@ void CheckForLocalPlayer(NetworkIdentity identity) { // Set isLocalPlayer to true on this NetworkIdentity and trigger OnStartLocalPlayer in all scripts on the same GO identity.connectionToServer = connection; - identity.OnStartLocalPlayer(); + identity.StartLocalPlayer(); if (LogFilter.Debug) Debug.Log("ClientScene.OnOwnerMessage - player=" + identity.name); } diff --git a/Assets/Mirror/Runtime/NetworkIdentity.cs b/Assets/Mirror/Runtime/NetworkIdentity.cs index 3086ed7192b..513b7c5891c 100644 --- a/Assets/Mirror/Runtime/NetworkIdentity.cs +++ b/Assets/Mirror/Runtime/NetworkIdentity.cs @@ -4,6 +4,7 @@ using System.Security.Cryptography; using UnityEngine; using UnityEngine.Serialization; +using UnityEngine.Events; #if UNITY_EDITOR using UnityEditor; #if UNITY_2018_3_OR_NEWER @@ -186,6 +187,45 @@ internal set // keep track of all sceneIds to detect scene duplicates static readonly Dictionary sceneIds = new Dictionary(); + /// + /// This is invoked for NetworkBehaviour objects when they become active on the server. + /// This could be triggered by NetworkServer.Listen() for objects in the scene, or by NetworkServer.Spawn() for objects that are dynamically created. + /// This will be called for objects on a "host" as well as for object on a dedicated server. + /// + public UnityEvent OnStartServer = new UnityEvent(); + + /// + /// Called on every NetworkBehaviour when it is activated on a client. + /// Objects on the host have this function called, as there is a local client on the host. The values of SyncVars on object are guaranteed to be initialized correctly with the latest state from the server when this function is called on the client. + /// + public UnityEvent OnStartClient = new UnityEvent(); + + /// + /// Called when the local player object has been set up. + /// This happens after OnStartClient(), as it is triggered by an ownership message from the server. This is an appropriate place to activate components or functionality that should only be active for the local player, such as cameras and input. + /// + public UnityEvent OnStartLocalPlayer = new UnityEvent(); + + /// + /// This is invoked on behaviours that have authority, based on context and NetworkIdentity.hasAuthority. + /// This is called after OnStartServer and before OnStartClient. + /// When is called on the server, this will be called on the client that owns the object. When an object is spawned with NetworkServer.Spawn with a NetworkConnection parameter included, this will be called on the client that owns the object. + /// + public UnityEvent OnStartAuthority = new UnityEvent(); + + /// + /// This is invoked on behaviours when authority is removed. + /// When NetworkIdentity.RemoveClientAuthority is called on the server, this will be called on the client that owns the object. + /// + public UnityEvent OnStopAuthority = new UnityEvent(); + + /// + /// This is invoked on clients when the server has caused this object to be destroyed. + /// This can be used as a hook to invoke effects or do client specific cleanup. + /// + ///Called on clients when the server destroys the GameObject. + public UnityEvent OnNetworkDestroy = new UnityEvent(); + /// /// Gets the NetworkIdentity from the sceneIds dictionary with the corresponding id /// @@ -501,7 +541,7 @@ void OnDestroy() } } - internal void OnStartServer() + internal void StartServer() { // If the instance/net ID is invalid here then this is an object instantiated from a prefab and the server should assign a valid ID if (netId != 0) @@ -521,124 +561,47 @@ internal void OnStartServer() // because we already set m_isServer=true above) server.spawned[netId] = this; - foreach (NetworkBehaviour comp in NetworkBehaviours) - { - // an exception in OnStartServer should be caught, so that one - // component's exception doesn't stop all other components from - // being initialized - // => this is what Unity does for Start() etc. too. - // one exception doesn't stop all the other Start() calls! - try - { - comp.OnStartServer(); - } - catch (Exception e) - { - Debug.LogError("Exception in OnStartServer:" + e.Message + " " + e.StackTrace); - } - } + OnStartServer.Invoke(); } bool clientStarted; - internal void OnStartClient() + internal void StartClient() { if (clientStarted) return; clientStarted = true; - if (LogFilter.Debug) Debug.Log("OnStartClient " + gameObject + " netId:" + netId); - foreach (NetworkBehaviour comp in NetworkBehaviours) - { - // an exception in OnStartClient should be caught, so that one - // component's exception doesn't stop all other components from - // being initialized - // => this is what Unity does for Start() etc. too. - // one exception doesn't stop all the other Start() calls! - try - { - // user implemented startup - comp.OnStartClient(); - } - catch (Exception e) - { - Debug.LogError("Exception in OnStartClient:" + e.Message + " " + e.StackTrace); - } - } + OnStartClient.Invoke(); } static NetworkIdentity previousLocalPlayer = null; - internal void OnStartLocalPlayer() + internal void StartLocalPlayer() { if (previousLocalPlayer == this) return; previousLocalPlayer = this; - foreach (NetworkBehaviour comp in NetworkBehaviours) - { - // an exception in OnStartLocalPlayer should be caught, so that - // one component's exception doesn't stop all other components - // from being initialized - // => this is what Unity does for Start() etc. too. - // one exception doesn't stop all the other Start() calls! - try - { - comp.OnStartLocalPlayer(); - } - catch (Exception e) - { - Debug.LogError("Exception in OnStartLocalPlayer:" + e.Message + " " + e.StackTrace); - } - } + OnStartLocalPlayer.Invoke(); } bool hadAuthority; internal void NotifyAuthority() { if (!hadAuthority && hasAuthority) - OnStartAuthority(); + StartAuthority(); if (hadAuthority && !hasAuthority) - OnStopAuthority(); + StopAuthority(); hadAuthority = hasAuthority; } - internal void OnStartAuthority() + internal void StartAuthority() { - foreach (NetworkBehaviour comp in NetworkBehaviours) - { - // an exception in OnStartAuthority should be caught, so that one - // component's exception doesn't stop all other components from - // being initialized - // => this is what Unity does for Start() etc. too. - // one exception doesn't stop all the other Start() calls! - try - { - comp.OnStartAuthority(); - } - catch (Exception e) - { - Debug.LogError("Exception in OnStartAuthority:" + e.Message + " " + e.StackTrace); - } - } + OnStartAuthority.Invoke(); } - internal void OnStopAuthority() + internal void StopAuthority() { - foreach (NetworkBehaviour comp in NetworkBehaviours) - { - // an exception in OnStopAuthority should be caught, so that one - // component's exception doesn't stop all other components from - // being initialized - // => this is what Unity does for Start() etc. too. - // one exception doesn't stop all the other Start() calls! - try - { - comp.OnStopAuthority(); - } - catch (Exception e) - { - Debug.LogError("Exception in OnStopAuthority:" + e.Message + " " + e.StackTrace); - } - } + OnStopAuthority.Invoke(); } internal void OnSetHostVisibility(bool visible) @@ -673,24 +636,9 @@ internal bool OnCheckObserver(NetworkConnection conn) return true; } - internal void OnNetworkDestroy() + internal void NetworkDestroy() { - foreach (NetworkBehaviour comp in NetworkBehaviours) - { - // an exception in OnNetworkDestroy should be caught, so that - // one component's exception doesn't stop all other components - // from being initialized - // => this is what Unity does for Start() etc. too. - // one exception doesn't stop all the other Start() calls! - try - { - comp.OnNetworkDestroy(); - } - catch (Exception e) - { - Debug.LogError("Exception in OnNetworkDestroy:" + e.Message + " " + e.StackTrace); - } - } + OnNetworkDestroy.Invoke(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Assets/Mirror/Runtime/NetworkServer.cs b/Assets/Mirror/Runtime/NetworkServer.cs index ba9f843fce2..07340514223 100644 --- a/Assets/Mirror/Runtime/NetworkServer.cs +++ b/Assets/Mirror/Runtime/NetworkServer.cs @@ -250,7 +250,7 @@ internal void ActivateHostScene() { if (LogFilter.Debug) Debug.Log("ActivateHostScene " + identity.netId + " " + identity); - identity.OnStartClient(); + identity.StartClient(); } } } @@ -892,7 +892,7 @@ internal void SpawnObject(GameObject obj, NetworkConnection ownerConnection) if (ownerConnection is ULocalConnectionToClient) identity.hasAuthority = true; - identity.OnStartServer(); + identity.StartServer(); if (LogFilter.Debug) Debug.Log("SpawnObject instance ID " + identity.netId + " asset ID " + identity.assetId); @@ -1058,7 +1058,7 @@ void DestroyObject(NetworkIdentity identity, bool destroyServerObject) identity.ClearObservers(); if (LocalClientActive) { - identity.OnNetworkDestroy(); + identity.OnNetworkDestroy.Invoke(); } // when unspawning, dont destroy the server's object diff --git a/Assets/Mirror/Tests/Editor/NetworkIdentityTests.cs b/Assets/Mirror/Tests/Editor/NetworkIdentityTests.cs index 0c208e65d10..b3d2cc5da76 100644 --- a/Assets/Mirror/Tests/Editor/NetworkIdentityTests.cs +++ b/Assets/Mirror/Tests/Editor/NetworkIdentityTests.cs @@ -12,22 +12,21 @@ namespace Mirror.Tests { public class NetworkIdentityTests { - #region test components + #region test components class MyTestComponent : NetworkBehaviour { internal bool onStartServerInvoked; - public override void OnStartServer() + public void OnStartServer() { onStartServerInvoked = true; - base.OnStartServer(); } } class StartServerExceptionNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnStartServer() + public void OnStartServer() { ++called; throw new Exception("some exception"); @@ -37,7 +36,7 @@ public override void OnStartServer() class StartClientExceptionNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnStartClient() + public void OnStartClient() { ++called; throw new Exception("some exception"); @@ -47,7 +46,7 @@ public override void OnStartClient() class StartAuthorityExceptionNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnStartAuthority() + public void OnStartAuthority() { ++called; throw new Exception("some exception"); @@ -57,13 +56,16 @@ public override void OnStartAuthority() class StartAuthorityCalledNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnStartAuthority() { ++called; } + public void OnStartAuthority() + { + ++called; + } } class StopAuthorityExceptionNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnStopAuthority() + public void OnStopAuthority() { ++called; throw new Exception("some exception"); @@ -73,13 +75,16 @@ public override void OnStopAuthority() class StopAuthorityCalledNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnStopAuthority() { ++called; } + public void OnStopAuthority() + { + ++called; + } } class StartLocalPlayerExceptionNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnStartLocalPlayer() + public void OnStartLocalPlayer() { ++called; throw new Exception("some exception"); @@ -89,13 +94,16 @@ public override void OnStartLocalPlayer() class StartLocalPlayerCalledNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnStartLocalPlayer() { ++called; } + public void OnStartLocalPlayer() + { + ++called; + } } class NetworkDestroyExceptionNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnNetworkDestroy() + public void OnNetworkDestroy() { ++called; throw new Exception("some exception"); @@ -105,7 +113,10 @@ public override void OnNetworkDestroy() class NetworkDestroyCalledNetworkBehaviour : NetworkBehaviour { public int called; - public override void OnNetworkDestroy() { ++called; } + public void OnNetworkDestroy() + { + ++called; + } } class SetHostVisibilityExceptionNetworkBehaviour : NetworkBehaviour @@ -275,14 +286,15 @@ public void OnStartServerTest() MyTestComponent component1 = gameObject.AddComponent(); MyTestComponent component2 = gameObject.AddComponent(); - identity.OnStartServer(); + identity.OnStartServer.AddListener(component1.OnStartServer); + identity.OnStartServer.AddListener(component2.OnStartServer); + + identity.StartServer(); Assert.That(component1.onStartServerInvoked); Assert.That(component2.onStartServerInvoked); } - - [Test] public void GetSetAssetId() { @@ -325,7 +337,7 @@ public void SetOverrideClientOwner() public void RemoveObserverInternal() { // call OnStartServer so that observers dict is created - identity.OnStartServer(); + identity.StartServer(); // add an observer connection var connection = new NetworkConnectionToClient(42); @@ -391,18 +403,14 @@ public void OnStartServerCallsComponentsAndCatchesExceptions() { // add component StartServerExceptionNetworkBehaviour comp = gameObject.AddComponent(); + identity.OnStartServer.AddListener(comp.OnStartServer); - // make sure that comp.OnStartServer was called and make sure that + // make sure that comp.OnStartServer was called // the exception was caught and not thrown in here. - // an exception in OnStartServer should be caught, so that one - // component's exception doesn't stop all other components from - // being initialized - // (an error log is expected though) - LogAssert.ignoreFailingMessages = true; - // should catch the exception internally and not throw it - identity.OnStartServer(); + Assert.Throws( () => { + identity.StartServer(); + }); Assert.That(comp.called, Is.EqualTo(1)); - LogAssert.ignoreFailingMessages = false; } [Test] @@ -410,24 +418,21 @@ public void OnStartClientCallsComponentsAndCatchesExceptions() { // add component StartClientExceptionNetworkBehaviour comp = gameObject.AddComponent(); + identity.OnStartClient.AddListener(comp.OnStartClient); - // make sure that comp.OnStartClient was called and make sure that + // make sure that comp.OnStartServer was called // the exception was caught and not thrown in here. - // an exception in OnStartClient should be caught, so that one - // component's exception doesn't stop all other components from - // being initialized - // (an error log is expected though) - LogAssert.ignoreFailingMessages = true; - // should catch the exception internally and not throw it - identity.OnStartClient(); + Assert.Throws( () => { + identity.StartClient(); + }); Assert.That(comp.called, Is.EqualTo(1)); - LogAssert.ignoreFailingMessages = false; + // we have checks to make sure that it's only called once. - // let's see if they work. - identity.OnStartClient(); - // same as before? - Assert.That(comp.called, Is.EqualTo(1)); + Assert.DoesNotThrow(() => { + identity.StartClient(); + }); + Assert.That(comp.called, Is.EqualTo(1)); } [Test] @@ -435,18 +440,14 @@ public void OnStartAuthorityCallsComponentsAndCatchesExceptions() { // add component StartAuthorityExceptionNetworkBehaviour comp = gameObject.AddComponent(); + identity.OnStartAuthority.AddListener(comp.OnStartAuthority); - // make sure that comp.OnStartAuthority was called and make sure that + // make sure that comp.OnStartServer was called // the exception was caught and not thrown in here. - // an exception in OnStartAuthority should be caught, so that one - // component's exception doesn't stop all other components from - // being initialized - // (an error log is expected though) - LogAssert.ignoreFailingMessages = true; - // should catch the exception internally and not throw it - identity.OnStartAuthority(); + Assert.Throws( () => { + identity.StartAuthority(); + }); Assert.That(comp.called, Is.EqualTo(1)); - LogAssert.ignoreFailingMessages = false; } [Test] @@ -454,18 +455,14 @@ public void OnStopAuthorityCallsComponentsAndCatchesExceptions() { // add component StopAuthorityExceptionNetworkBehaviour comp = gameObject.AddComponent(); - - // make sure that comp.OnStopAuthority was called and make sure that + identity.OnStopAuthority.AddListener(comp.OnStopAuthority); + + // make sure that comp.OnStartServer was called // the exception was caught and not thrown in here. - // an exception in OnStopAuthority should be caught, so that one - // component's exception doesn't stop all other components from - // being initialized - // (an error log is expected though) - LogAssert.ignoreFailingMessages = true; - // should catch the exception internally and not throw it - identity.OnStopAuthority(); + Assert.Throws( () => { + identity.StopAuthority(); + }); Assert.That(comp.called, Is.EqualTo(1)); - LogAssert.ignoreFailingMessages = false; } [Test] @@ -473,7 +470,9 @@ public void NotifyAuthorityCallsOnStartStopAuthority() { // add components StartAuthorityCalledNetworkBehaviour compStart = gameObject.AddComponent(); + identity.OnStartAuthority.AddListener(compStart.OnStartAuthority); StopAuthorityCalledNetworkBehaviour compStop = gameObject.AddComponent(); + identity.OnStopAuthority.AddListener(compStop.OnStopAuthority); // set authority from false to true, which should call OnStartAuthority identity.hasAuthority = true; @@ -708,29 +707,33 @@ public void OnStartLocalPlayer() { // add components StartLocalPlayerExceptionNetworkBehaviour compEx = gameObject.AddComponent(); + identity.OnStartLocalPlayer.AddListener(compEx.OnStartLocalPlayer); StartLocalPlayerCalledNetworkBehaviour comp = gameObject.AddComponent(); + identity.OnStartLocalPlayer.AddListener(comp.OnStartLocalPlayer); // make sure our test values are set to 0 Assert.That(compEx.called, Is.EqualTo(0)); Assert.That(comp.called, Is.EqualTo(0)); - // call OnStartLocalPlayer in identity - // one component will throw an exception, but that shouldn't stop - // OnStartLocalPlayer from being called in the second one - // exception will log an error - LogAssert.ignoreFailingMessages = true; - identity.OnStartLocalPlayer(); - LogAssert.ignoreFailingMessages = false; + // make sure that comp.OnStartServer was called + // the exception was caught and not thrown in here. + Assert.Throws( () => { + identity.StartLocalPlayer(); + }); + Assert.That(compEx.called, Is.EqualTo(1)); - Assert.That(comp.called, Is.EqualTo(1)); + //Due to the order the listeners are added the one without exception is never called + Assert.That(comp.called, Is.EqualTo(0)); // we have checks to make sure that it's only called once. // let's see if they work. - identity.OnStartLocalPlayer(); + Assert.DoesNotThrow( () => { + identity.StartLocalPlayer(); + }); // same as before? Assert.That(compEx.called, Is.EqualTo(1)); - // same as before? - Assert.That(comp.called, Is.EqualTo(1)); + //Due to the order the listeners are added the one without exception is never called + Assert.That(comp.called, Is.EqualTo(0)); } [Test] @@ -738,21 +741,23 @@ public void OnNetworkDestroy() { // add components NetworkDestroyExceptionNetworkBehaviour compEx = gameObject.AddComponent(); + identity.OnNetworkDestroy.AddListener(compEx.OnNetworkDestroy); NetworkDestroyCalledNetworkBehaviour comp = gameObject.AddComponent(); + identity.OnNetworkDestroy.AddListener(comp.OnNetworkDestroy); // make sure our test values are set to 0 Assert.That(compEx.called, Is.EqualTo(0)); Assert.That(comp.called, Is.EqualTo(0)); - // call OnNetworkDestroy in identity - // one component will throw an exception, but that shouldn't stop - // OnNetworkDestroy from being called in the second one - // exception will log an error - LogAssert.ignoreFailingMessages = true; - identity.OnNetworkDestroy(); - LogAssert.ignoreFailingMessages = false; + // we have checks to make sure that it's only called once. + // let's see if they work. + Assert.Throws( () => { + identity.NetworkDestroy(); + }); + Assert.That(compEx.called, Is.EqualTo(1)); - Assert.That(comp.called, Is.EqualTo(1)); + //Due to the order the listeners are added the one without exception is never called + Assert.That(comp.called, Is.EqualTo(0)); } [Test] @@ -774,7 +779,7 @@ public void AddObserver() Assert.That(identity.observers, Is.Null); // call OnStartServer so that observers dict is created - identity.OnStartServer(); + identity.StartServer(); // call AddObservers identity.AddObserver(connection1); @@ -790,7 +795,7 @@ public void AddObserver() public void ClearObservers() { // call OnStartServer so that observers dict is created - identity.OnStartServer(); + identity.StartServer(); // add some observers identity.observers.Add(new NetworkConnectionToClient(42)); @@ -807,7 +812,7 @@ public void Reset() { // modify it a bit // creates .observers and generates a netId - identity.OnStartServer(); + identity.StartServer(); uint netId = identity.netId; identity.connectionToClient = new NetworkConnectionToClient(1); identity.connectionToServer = new NetworkConnectionToServer(); @@ -848,7 +853,7 @@ public void ServerUpdate() compB.syncMode = SyncMode.Observers; // call OnStartServer once so observers are created - identity.OnStartServer(); + identity.StartServer(); // set it dirty compA.SetDirtyBit(ulong.MaxValue); @@ -956,7 +961,7 @@ public void AddAllReadyServerConnectionsToObservers() server.SetLocalConnection(client, localConnection); // call OnStartServer so that observers dict is created - identity.OnStartServer(); + identity.StartServer(); // add all to observers. should have the two ready connections then. identity.AddAllReadyServerConnectionsToObservers(); @@ -982,7 +987,7 @@ public void RebuildObserversAddsOwnReadyPlayer() identity.connectionToClient = connection; // call OnStartServer so that observers dict is created - identity.OnStartServer(); + identity.StartServer(); // rebuild should at least add own ready player identity.RebuildObservers(true); @@ -1003,12 +1008,12 @@ public void RebuildObserversOnlyAddsOwnPlayerIfReady() identity.connectionToClient = connection; // call OnStartServer so that observers dict is created - identity.OnStartServer(); + identity.StartServer(); // rebuild shouldn't add own player because conn wasn't set ready identity.RebuildObservers(true); Assert.That(identity.observers, Does.Not.Contains(identity.connectionToClient)); } - } + } } diff --git a/Assets/Mirror/Tests/Play/NetworkBehaviourTests.cs b/Assets/Mirror/Tests/Play/NetworkBehaviourTests.cs index be973f6be50..eb1aa1cfbaa 100644 --- a/Assets/Mirror/Tests/Play/NetworkBehaviourTests.cs +++ b/Assets/Mirror/Tests/Play/NetworkBehaviourTests.cs @@ -65,7 +65,7 @@ class OnStartServerTestComponent : NetworkBehaviour { public bool called = false; - public override void OnStartServer() + public void OnStartServer() { Assert.That(isClient, Is.True); Assert.That(isLocalPlayer, Is.False); @@ -79,13 +79,16 @@ public override void OnStartServer() public void OnStartServer() { var gameObject = new GameObject(); - gameObject.AddComponent(); + var netIdentity = gameObject.AddComponent(); var comp = gameObject.AddComponent(); + netIdentity.OnStartServer.AddListener(comp.OnStartServer); Assert.That(comp.called, Is.False); server.Spawn(gameObject); + netIdentity.StartServer(); + Assert.That(comp.called, Is.True); GameObject.DestroyImmediate(gameObject); diff --git a/Assets/Mirror/Tests/Play/NetworkServerTest.cs b/Assets/Mirror/Tests/Play/NetworkServerTest.cs index 73ce294661d..4209dad5106 100644 --- a/Assets/Mirror/Tests/Play/NetworkServerTest.cs +++ b/Assets/Mirror/Tests/Play/NetworkServerTest.cs @@ -49,14 +49,20 @@ public class OnStartClientTestNetworkBehaviour : NetworkBehaviour { // counter to make sure that it's called exactly once public int called; - public override void OnStartClient() { ++called; } + public void OnStartClient() + { + ++called; + } } public class OnNetworkDestroyTestNetworkBehaviour : NetworkBehaviour { // counter to make sure that it's called exactly once public int called; - public override void OnNetworkDestroy() { ++called; } + public void OnNetworkDestroy() + { + ++called; + } } [TestFixture] @@ -537,6 +543,7 @@ public void ActivateHostSceneCallsOnStartClient() Assert.That(comp.called, Is.EqualTo(0)); //connection.identity = identity; server.spawned[identity.netId] = identity; + identity.OnStartClient.AddListener(comp.OnStartClient); // ActivateHostScene server.ActivateHostScene();