feat: OnStopLocalPlayer (#2070) (#3076)

* OnStopLocalPlayer

* NB test

* stuff
This commit is contained in:
vis2k 2022-01-30 12:23:37 +08:00 committed by GitHub
parent 0ebe9cbbd2
commit 4a95f42c17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 99 additions and 6 deletions

View File

@ -827,6 +827,9 @@ public virtual void OnStopClient() {}
/// <summary>Like Start(), but only called on client and host for the local player object.</summary>
public virtual void OnStartLocalPlayer() {}
/// <summary>Stop event, but only called on client and host for the local player object.</summary>
public virtual void OnStopLocalPlayer() {}
/// <summary>Like Start(), but only called for objects the client has authority over.</summary>
public virtual void OnStartAuthority() {}

View File

@ -1308,6 +1308,9 @@ static void DestroyObject(uint netId)
// Debug.Log($"NetworkClient.OnObjDestroy netId: {netId}");
if (spawned.TryGetValue(netId, out NetworkIdentity localObject) && localObject != null)
{
if (localObject.isLocalPlayer)
localObject.OnStopLocalPlayer();
localObject.OnStopClient();
// user handling
@ -1389,7 +1392,11 @@ public static void DestroyAllClientObjects()
{
if (identity != null && identity.gameObject != null)
{
if (identity.isLocalPlayer)
identity.OnStopLocalPlayer();
identity.OnStopClient();
bool wasUnspawned = InvokeUnSpawnHandler(identity.assetId, identity.gameObject);
if (!wasUnspawned)
{

View File

@ -784,6 +784,26 @@ internal void OnStartLocalPlayer()
}
}
internal void OnStopLocalPlayer()
{
foreach (NetworkBehaviour comp in NetworkBehaviours)
{
// an exception in OnStopLocalPlayer 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.OnStopLocalPlayer();
}
catch (Exception e)
{
Debug.LogException(e, comp);
}
}
}
bool hadAuthority;
internal void NotifyAuthority()
{

View File

@ -1318,9 +1318,12 @@ static void DestroyObject(NetworkIdentity identity, DestroyMode mode)
SendToObservers(identity, new ObjectDestroyMessage{netId = identity.netId});
identity.ClearObservers();
// in host mode, call OnStopClient manually
// in host mode, call OnStopClient/OnStopLocalPlayer manually
if (NetworkClient.active && localClientActive)
{
if (identity.isLocalPlayer)
identity.OnStopLocalPlayer();
identity.OnStopClient();
// The object may have been spawned with host client ownership,
// e.g. a pet so we need to clear hasAuthority and call

View File

@ -87,6 +87,13 @@ public class OnStartLocalPlayerComponent : NetworkBehaviour
public override void OnStartLocalPlayer() => ++called;
}
// we need to inherit from networkbehaviour to test protected functions
public class OnStopLocalPlayerComponent : NetworkBehaviour
{
public int called;
public override void OnStopLocalPlayer() => ++called;
}
public class NetworkBehaviourTests : MirrorEditModeTest
{
[TearDown]
@ -867,6 +874,14 @@ public void OnStartLocalPlayer()
identity.OnStartLocalPlayer();
Assert.That(comp.called, Is.EqualTo(1));
}
[Test]
public void OnStopLocalPlayer()
{
CreateNetworked(out GameObject _, out NetworkIdentity identity, out OnStopLocalPlayerComponent comp);
identity.OnStopLocalPlayer();
Assert.That(comp.called, Is.EqualTo(1));
}
}
// we need to inherit from networkbehaviour to test protected functions

View File

@ -80,7 +80,7 @@ class StartLocalPlayerCalledNetworkBehaviour : NetworkBehaviour
public override void OnStartLocalPlayer() => ++called;
}
class NetworkDestroyExceptionNetworkBehaviour : NetworkBehaviour
class StopClientExceptionNetworkBehaviour : NetworkBehaviour
{
public int called;
public override void OnStopClient()
@ -90,12 +90,28 @@ public override void OnStopClient()
}
}
class NetworkDestroyCalledNetworkBehaviour : NetworkBehaviour
class StopClientCalledNetworkBehaviour : NetworkBehaviour
{
public int called;
public override void OnStopClient() => ++called;
}
class StopLocalPlayerCalledNetworkBehaviour : NetworkBehaviour
{
public int called;
public override void OnStopLocalPlayer() => ++called;
}
class StopLocalPlayerExceptionNetworkBehaviour : NetworkBehaviour
{
public int called;
public override void OnStopLocalPlayer()
{
++called;
throw new Exception("some exception");
}
}
class StopServerCalledNetworkBehaviour : NetworkBehaviour
{
public int called;
@ -755,11 +771,40 @@ public void OnStartLocalPlayer()
Assert.That(comp.called, Is.EqualTo(1));
}
[Test]
public void OnStopLocalPlayer()
{
CreateNetworked(out GameObject _, out NetworkIdentity identity,
out StopLocalPlayerCalledNetworkBehaviour comp);
// call OnStopLocalPlayer in identity
identity.OnStopLocalPlayer();
Assert.That(comp.called, Is.EqualTo(1));
}
[Test]
public void OnStopLocalPlayerException()
{
CreateNetworked(out GameObject _, out NetworkIdentity identity,
out StopLocalPlayerExceptionNetworkBehaviour compEx,
out StopLocalPlayerCalledNetworkBehaviour comp);
// call OnStopLocalPlayer in identity
// one component will throw an exception, but that shouldn't stop
// OnStopLocalPlayer from being called in the second one
// exception will log an error
LogAssert.ignoreFailingMessages = true;
identity.OnStopLocalPlayer();
LogAssert.ignoreFailingMessages = false;
Assert.That(compEx.called, Is.EqualTo(1));
Assert.That(comp.called, Is.EqualTo(1));
}
[Test]
public void OnStopClient()
{
CreateNetworked(out GameObject _, out NetworkIdentity identity,
out NetworkDestroyCalledNetworkBehaviour comp);
out StopClientCalledNetworkBehaviour comp);
// call OnStopClient in identity
identity.OnStopClient();
@ -770,8 +815,8 @@ public void OnStopClient()
public void OnStopClientException()
{
CreateNetworked(out GameObject _, out NetworkIdentity identity,
out NetworkDestroyExceptionNetworkBehaviour compEx,
out NetworkDestroyCalledNetworkBehaviour comp);
out StopClientExceptionNetworkBehaviour compEx,
out StopClientCalledNetworkBehaviour comp);
// call OnStopClient in identity
// one component will throw an exception, but that shouldn't stop