Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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!");
}
}
}