Skip to content

Commit 04fee31

Browse files
Merge branch 'develop-2.0.0' into fix/reset-networkclient-completely-upon-shutdown
2 parents d5bc844 + d4a9810 commit 04fee31

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

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

1515
- Fixed issue where `NetworkClient` could persist some settings if re-using the same `NetworkManager` instance. (#3491)
1616
- Fixed issue where a pooled `NetworkObject` was not resetting the internal latest parent property when despawned. (#3491)
17+
- Fixed issue where the initial client synchronization pre-serialization process was not excluding spawned `NetworkObject` instances that already had pending visibility for the client being synchronized. (#3488)
1718
- Fixed issue where there was a potential for a small memory leak in the `ConnectionApprovedMessage`. (#3486)
1819

1920
### Changed

com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,12 @@ internal void AddSpawnedNetworkObjects()
324324
var distributedAuthoritySendingToService = m_NetworkManager.DistributedAuthorityMode && TargetClientId == NetworkManager.ServerClientId;
325325
foreach (var sobj in m_NetworkManager.SpawnManager.SpawnedObjectsList)
326326
{
327+
var spawnedObject = sobj;
328+
// Don't synchronize objects that have pending visibility as that will be sent as a CreateObjectMessage towards the end of the current frame
329+
if (TargetClientId != NetworkManager.ServerClientId && m_NetworkManager.SpawnManager.IsObjectVisibilityPending(TargetClientId, ref spawnedObject))
330+
{
331+
continue;
332+
}
327333
if (sobj.Observers.Contains(TargetClientId) || distributedAuthoritySendingToService)
328334
{
329335
m_NetworkObjectsSync.Add(sobj);
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using System.Collections;
2+
using System.Text.RegularExpressions;
3+
using NUnit.Framework;
4+
using Unity.Netcode.TestHelpers.Runtime;
5+
using UnityEngine;
6+
using UnityEngine.TestTools;
7+
8+
9+
namespace Unity.Netcode.RuntimeTests
10+
{
11+
[TestFixture(HostOrServer.Server)]
12+
[TestFixture(HostOrServer.Host)]
13+
internal class PlayerSpawnObjectVisibilityTests : NetcodeIntegrationTest
14+
{
15+
protected override int NumberOfClients => 0;
16+
17+
public enum PlayerSpawnStages
18+
{
19+
OnNetworkSpawn,
20+
OnNetworkPostSpawn,
21+
}
22+
23+
public PlayerSpawnObjectVisibilityTests(HostOrServer hostOrServer) : base(hostOrServer) { }
24+
25+
public class PlayerVisibilityTestComponent : NetworkBehaviour
26+
{
27+
public PlayerSpawnStages Stage;
28+
29+
private void Awake()
30+
{
31+
var networkObject = GetComponent<NetworkObject>();
32+
// Assure the player prefab will not spawn with observers.
33+
// This assures that when the server/host spawns the connecting client's
34+
// player prefab, the spawn object will initially not be spawnd on the client side.
35+
networkObject.SpawnWithObservers = false;
36+
}
37+
38+
public override void OnNetworkSpawn()
39+
{
40+
ShowToClient(PlayerSpawnStages.OnNetworkSpawn);
41+
base.OnNetworkSpawn();
42+
}
43+
44+
protected override void OnNetworkPostSpawn()
45+
{
46+
ShowToClient(PlayerSpawnStages.OnNetworkPostSpawn);
47+
base.OnNetworkPostSpawn();
48+
}
49+
50+
private void ShowToClient(PlayerSpawnStages currentStage)
51+
{
52+
if (!HasAuthority || Stage != currentStage)
53+
{
54+
return;
55+
}
56+
NetworkObject.NetworkShow(OwnerClientId);
57+
}
58+
}
59+
60+
protected override void OnCreatePlayerPrefab()
61+
{
62+
m_PlayerPrefab.AddComponent<PlayerVisibilityTestComponent>();
63+
base.OnCreatePlayerPrefab();
64+
}
65+
66+
/// <summary>
67+
/// Tests the scenario where under a client-server network topology if a player prefab
68+
/// is spawned by the server with no observers but the player prefab itself has server
69+
/// side script that will network show the spawned object to the owning client.
70+
///
71+
/// Because NetworkShow will defer the CreateObjectMessage until the late update, the
72+
/// server/host needs to filter out including anything within the synchronization
73+
/// message that already has pending visibility.
74+
/// </summary>
75+
/// <param name="spawnStage">Spawn stages to test</param>
76+
/// <returns>IEnumerator</returns>
77+
[UnityTest]
78+
public IEnumerator NetworkShowOnSpawnTest([Values] PlayerSpawnStages spawnStage)
79+
{
80+
m_PlayerPrefab.GetComponent<PlayerVisibilityTestComponent>().Stage = spawnStage;
81+
82+
yield return CreateAndStartNewClient();
83+
84+
yield return new WaitForSeconds(0.25f);
85+
86+
NetcodeLogAssert.LogWasNotReceived(LogType.Warning, new Regex("but it is already in the spawned list!"));
87+
var client = GetNonAuthorityNetworkManager();
88+
Assert.True(client.LocalClient.PlayerObject != null, $"Client-{client.LocalClientId} does not have a player object!");
89+
}
90+
}
91+
}

com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/PlayerSpawnObjectVisibilityTests.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)