Skip to content

Commit 0d3718f

Browse files
NoelStephensUnityjakobbbb
authored andcommitted
fix: Migrate OnClientConnectedCallback invocation into StartHost [MTT-4972] (Unity-Technologies#2277)
* fix Migrate InvokeOnClientConnectedCallback into StartHost (for host only). * test Updating the NetworkManagerTests to validate this PR, it also validates that this update does not impact anything when scene management is disabled.
1 parent a4d1992 commit 0d3718f

4 files changed

Lines changed: 104 additions & 4 deletions

File tree

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1111

1212
### Fixed
1313

14+
- Fixed the issue where `NetworkManager.OnClientConnectedCallback` was being invoked before in-scene placed `NetworkObject`s had been spawned when starting `NetworkManager` as a host. (#2277)
1415
- Creating a `FastBufferReader` with `Allocator.None` will not result in extra memory being allocated for the buffer (since it's owned externally in that scenario). (#2265)
1516

1617
## [1.1.0] - 2022-10-21

com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,11 @@ public bool StartHost()
11881188

11891189
SpawnManager.ServerSpawnSceneObjectsOnStartSweep();
11901190

1191+
// This assures that any in-scene placed NetworkObject is spawned and
1192+
// any associated NetworkBehaviours' netcode related properties are
1193+
// set prior to invoking OnClientConnected.
1194+
InvokeOnClientConnectedCallback(LocalClientId);
1195+
11911196
OnServerStarted?.Invoke();
11921197

11931198
return true;
@@ -2226,7 +2231,6 @@ internal void HandleConnectionApproval(ulong ownerClientId, ConnectionApprovalRe
22262231
{
22272232
LocalClient = client;
22282233
SpawnManager.UpdateObservedNetworkObjects(ownerClientId);
2229-
InvokeOnClientConnectedCallback(ownerClientId);
22302234
}
22312235

22322236
if (!response.CreatePlayerObject || (response.PlayerPrefabHash == null && NetworkConfig.PlayerPrefab == null))
Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,95 @@
11
using NUnit.Framework;
2+
using UnityEngine;
3+
using UnityEngine.SceneManagement;
4+
using Unity.Netcode;
25
using Unity.Netcode.TestHelpers.Runtime;
3-
6+
using System.Collections;
47

58
namespace TestProject.RuntimeTests
69
{
10+
[TestFixture(UseSceneManagement.SceneManagementDisabled)]
11+
[TestFixture(UseSceneManagement.SceneManagementEnabled)]
712
public class NetworkManagerTests : NetcodeIntegrationTest
813
{
9-
protected override int NumberOfClients => 1;
14+
private const string k_SceneToLoad = "InSceneNetworkObject";
15+
protected override int NumberOfClients => 0;
16+
17+
public enum UseSceneManagement
18+
{
19+
SceneManagementEnabled,
20+
SceneManagementDisabled
21+
}
22+
23+
private bool m_EnableSceneManagement;
24+
private NetworkObject m_NetworkObject;
25+
private bool m_NetworkObjectWasSpawned;
26+
private bool m_NetworkBehaviourIsHostWasSet;
27+
private bool m_NetworkBehaviourIsClientWasSet;
28+
private bool m_NetworkBehaviourIsServerWasSet;
29+
private int m_NumberOfTimesInvoked;
30+
private AsyncOperation m_AsyncOperation;
31+
private NetworkObjectTestComponent m_NetworkObjectTestComponent;
32+
33+
private bool m_UseSceneManagement;
34+
35+
public NetworkManagerTests(UseSceneManagement useSceneManagement)
36+
{
37+
m_UseSceneManagement = useSceneManagement == UseSceneManagement.SceneManagementEnabled;
38+
}
39+
40+
private void OnClientConnectedCallback(NetworkObject networkObject, int numberOfTimesInvoked, bool isHost, bool isClient, bool isServer)
41+
{
42+
m_NetworkObject = networkObject;
43+
m_NetworkObjectWasSpawned = networkObject.IsSpawned;
44+
m_NetworkBehaviourIsHostWasSet = isHost;
45+
m_NetworkBehaviourIsClientWasSet = isClient;
46+
m_NetworkBehaviourIsServerWasSet = isServer;
47+
m_NumberOfTimesInvoked = numberOfTimesInvoked;
48+
}
49+
50+
private bool TestComponentFound()
51+
{
52+
if (!m_AsyncOperation.isDone)
53+
{
54+
return false;
55+
}
56+
57+
m_NetworkObjectTestComponent = Object.FindObjectOfType<NetworkObjectTestComponent>();
58+
if (m_NetworkObjectTestComponent == null)
59+
{
60+
return false;
61+
}
62+
return true;
63+
}
64+
65+
protected override IEnumerator OnSetup()
66+
{
67+
m_AsyncOperation = SceneManager.LoadSceneAsync(k_SceneToLoad, LoadSceneMode.Additive);
68+
yield return WaitForConditionOrTimeOut(TestComponentFound);
69+
AssertOnTimeout($"Failed to find {nameof(NetworkObjectTestComponent)} after loading test scene {k_SceneToLoad}");
70+
}
71+
72+
protected override IEnumerator OnTearDown()
73+
{
74+
SceneManager.UnloadSceneAsync(SceneManager.GetSceneByName(k_SceneToLoad));
75+
yield return s_DefaultWaitForTick;
76+
}
77+
78+
protected override void OnServerAndClientsCreated()
79+
{
80+
m_ServerNetworkManager.NetworkConfig.EnableSceneManagement = m_EnableSceneManagement;
81+
m_NetworkObjectTestComponent.ConfigureClientConnected(m_ServerNetworkManager, OnClientConnectedCallback);
82+
}
1083

1184
[Test]
12-
public void ValidateHostLocalClient()
85+
public void ValidateHostSettings()
1386
{
1487
Assert.IsTrue(m_ServerNetworkManager.LocalClient != null);
88+
Assert.IsTrue(m_NetworkObjectWasSpawned, $"{m_NetworkObject.name} was not spawned when OnClientConnectedCallback was invoked!");
89+
Assert.IsTrue(m_NetworkBehaviourIsHostWasSet, $"IsHost was not true when OnClientConnectedCallback was invoked!");
90+
Assert.IsTrue(m_NetworkBehaviourIsClientWasSet, $"IsClient was not true when OnClientConnectedCallback was invoked!");
91+
Assert.IsTrue(m_NumberOfTimesInvoked == 1, $"OnClientConnectedCallback was invoked {m_NumberOfTimesInvoked} as opposed to just once!");
92+
Assert.IsTrue(m_NetworkBehaviourIsServerWasSet, $"IsServer was not true when OnClientConnectedCallback was invoked!");
1593
}
1694
}
1795
}

testproject/Assets/Tests/Runtime/NetworkSceneManager/NetworkObjectTestComponent.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ public static void Reset()
2727
DespawnedInstances.Clear();
2828
}
2929

30+
private Action<NetworkObject, int, bool, bool, bool> m_ActionClientConnected;
31+
private int m_NumberOfTimesInvoked;
32+
public void ConfigureClientConnected(NetworkManager networkManager, Action<NetworkObject, int, bool, bool, bool> clientConnected)
33+
{
34+
networkManager.OnClientConnectedCallback += NetworkManager_OnClientConnectedCallback;
35+
m_ActionClientConnected = clientConnected;
36+
}
37+
38+
private void NetworkManager_OnClientConnectedCallback(ulong obj)
39+
{
40+
m_NumberOfTimesInvoked++;
41+
if (m_ActionClientConnected != null)
42+
{
43+
m_ActionClientConnected.Invoke(NetworkObject, m_NumberOfTimesInvoked, IsHost, IsClient, IsServer);
44+
}
45+
}
46+
3047
// When disabling on spawning we only want this to happen on the initial spawn.
3148
// This is used to track this so the server only does it once upon spawning.
3249
public bool ObjectWasDisabledUponSpawn;

0 commit comments

Comments
 (0)