Skip to content

Commit b5f82ee

Browse files
fix: Migrate OnClientConnectedCallback invocation into StartHost [MTT-4972] (#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 fc6e757 commit b5f82ee

File tree

4 files changed

+104
-4
lines changed

4 files changed

+104
-4
lines changed

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
@@ -1181,6 +1181,11 @@ public bool StartHost()
11811181

11821182
SpawnManager.ServerSpawnSceneObjectsOnStartSweep();
11831183

1184+
// This assures that any in-scene placed NetworkObject is spawned and
1185+
// any associated NetworkBehaviours' netcode related properties are
1186+
// set prior to invoking OnClientConnected.
1187+
InvokeOnClientConnectedCallback(LocalClientId);
1188+
11841189
OnServerStarted?.Invoke();
11851190

11861191
return true;
@@ -2219,7 +2224,6 @@ internal void HandleConnectionApproval(ulong ownerClientId, ConnectionApprovalRe
22192224
{
22202225
LocalClient = client;
22212226
SpawnManager.UpdateObservedNetworkObjects(ownerClientId);
2222-
InvokeOnClientConnectedCallback(ownerClientId);
22232227
}
22242228

22252229
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)