Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
- The default listen address of `UnityTransport` is now 0.0.0.0. (#2307)

### Fixed
- Fixed server side issue where, depending upon component ordering, some NetworkBehaviour components might not have their OnNetworkDespawn method invoked if the client side disconnected. (#2323)

- Fixed an issue in `UnityTransport` where an exception would be thrown if starting a Relay host/server on WebGL. This exception should only be thrown if using direct connections (where WebGL can't act as a host/server). (#2321)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2082,7 +2082,12 @@ private void OnClientDisconnectFromServer(ulong clientId)
}
else
{
Destroy(playerObject.gameObject);
// Call despawn to assure NetworkBehaviour.OnNetworkDespawn is invoked
// on the server-side (when the client side disconnected).
// This prevents the issue (when just destroying the GameObject) where
// any NetworkBehaviour component(s) destroyed before the NetworkObject
// would not have OnNetworkDespawn invoked.
SpawnManager.DespawnObject(playerObject, true);
}
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,20 @@ protected virtual void OnCreatePlayerPrefab()
{
}

/// <summary>
/// Invoked immediately after the player prefab GameObject is created
/// prior to adding a NetworkObject component
/// </summary>
protected virtual void OnPlayerPrefabGameObjectCreated()
{
}

private void CreatePlayerPrefab()
{
VerboseDebug($"Entering {nameof(CreatePlayerPrefab)}");
// Create playerPrefab
m_PlayerPrefab = new GameObject("Player");
OnPlayerPrefabGameObjectCreated();
NetworkObject networkObject = m_PlayerPrefab.AddComponent<NetworkObject>();

// Make it a prefab
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections;
using UnityEngine;
using NUnit.Framework;
using UnityEngine.TestTools;
using Unity.Netcode.TestHelpers.Runtime;
using Unity.Netcode.Components;
Expand Down Expand Up @@ -147,5 +148,35 @@ public IEnumerator ValidateDeleteChildNetworkBehaviour()
// (validating the fix)
Object.Destroy(parentObject);
}

protected override void OnPlayerPrefabGameObjectCreated()
{
// Adds the SimpleNetworkBehaviour before the NetworkObject
// for OnNetworkDespawnInvokedWhenClientDisconnects testing
m_PlayerPrefab.AddComponent<SimpleNetworkBehaviour>();
}

/// <summary>
/// This validates that upon a client disconnecting, the server-side
/// client's player clone will invoke NetworkBehaviour.OnNetworkDespawn
/// when the component precedes the NetworkObject component.(PR-2323)
/// </summary>
[UnityTest]
public IEnumerator OnNetworkDespawnInvokedWhenClientDisconnects()
{
m_AllowServerToStart = true;

// Now just start the Host
yield return StartServerAndClients();

// Now create and connect a new client
yield return CreateAndStartNewClient();

var serverSidePlayer = m_PlayerNetworkObjects[NetworkManager.ServerClientId][m_ClientNetworkManagers[0].LocalClientId].GetComponent<SimpleNetworkBehaviour>();

yield return StopOneClient(m_ClientNetworkManagers[0]);

Assert.True(serverSidePlayer.OnNetworkDespawnCalled, $"Server-side player clone did not invoke OnNetworkDespawn!");
}
}
}