Skip to content

Commit c005085

Browse files
Merge develop-3.x.x into fix/player-test-failures-uum-160259
2 parents 719df97 + ae5f643 commit c005085

3 files changed

Lines changed: 63 additions & 7 deletions

File tree

‎com.unity.netcode.gameobjects/CHANGELOG.md‎

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

1919
### Fixed
2020

21+
- Issue where every `NetworkObject` that started before a session logged a "Did not register because there is no session in progress!" warning when `NetworkManager.LogLevel` was `Developer`. Only `GhostObject` instances log it now. (#4245)
2122
- Fixed a NullReferenceException that would be thrown if a MonoBehaviour derived from NetworkManager defines it's own Awake or OnEnable. (#4244)
2223
- Issue where the unified bootstrap created a second world that ran a duplicate of every default system next to the default world. (#4243)
2324
- Ensured a useful and human readable error is logged when a NetworkVariable is trying to serialize a private or protected type. (#4239)

‎com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4208,6 +4208,8 @@ private void Start()
42084208
[HideInInspector]
42094209
internal NetworkObjectBridge NetworkObjectBridge;
42104210

4211+
internal const string NotRegisteredWithoutSessionWarning = "Did not register because there is no session in progress!";
4212+
42114213
private void InitGhost()
42124214
{
42134215
// Note: If hybrid prefabs are created prior to any NetworkManager instances,
@@ -4220,22 +4222,21 @@ private void InitGhost()
42204222
return;
42214223
}
42224224

4225+
if (!HasGhost || !NetworkObjectBridge || GhostObject.IsPrefab())
4226+
{
4227+
// Nothing to register
4228+
return;
4229+
}
42234230

42244231
if (!NetworkManager.IsListening)
42254232
{
42264233
if (NetworkManager.LogLevel == LogLevel.Developer)
42274234
{
4228-
Debug.LogWarning($"[{nameof(NetworkObject)}] Did not register because there is no session in progress!");
4235+
Debug.LogWarning($"[{nameof(NetworkObject)}][{name}] {NotRegisteredWithoutSessionWarning}");
42294236
}
42304237
return;
42314238
}
42324239

4233-
if (!HasGhost || !NetworkObjectBridge || GhostObject.IsPrefab())
4234-
{
4235-
// Nothing to register
4236-
return;
4237-
}
4238-
42394240
// All instances with Ghosts are automatically registered
42404241
if (NetworkManager.LogLevel == LogLevel.Developer)
42414242
{

‎com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/UnifiedHybridPrefabValidationTests.cs‎

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#if UNIFIED_NETCODE
22
using System;
33
using System.Collections;
4+
using System.Collections.Generic;
45
using System.Text.RegularExpressions;
56
using NUnit.Framework;
67
using Unity.Netcode.TestHelpers.Runtime;
@@ -17,6 +18,7 @@ namespace Unity.Netcode.RuntimeTests
1718
/// - A hybrid prefab instance spawned during a session that started without hybrid prefabs. It is not spawned.<br />
1819
/// - A hybrid player prefab counts toward hybrid mode before the session starts, so distributed authority rejects it.<br />
1920
/// - A NetworkPrefab override with a hybrid source or target prefab, in any topology. The entry is ignored.<br />
21+
/// - A hybrid instance created before the session starts. With developer logging it warns, and a non-hybrid instance does not.<br />
2022
/// </summary>
2123
/// <remarks>
2224
/// The fixture's managers are not started. Each test creates its own <see cref="NetworkManager"/> that registers only the prefabs it needs.
@@ -215,6 +217,58 @@ public void PrefabListAddDuringSessionRegistersOnce()
215217
UnityEngine.Object.Destroy(prefabList);
216218
}
217219

220+
/// <summary>
221+
/// Validates that only a hybrid instance created before the session starts warns that it was not registered.
222+
/// </summary>
223+
[UnityTest]
224+
public IEnumerator PreSessionInstanceWarnsOnlyWhenHybrid()
225+
{
226+
var networkManager = CreateNetworkManager(NetworkTopologyTypes.ClientServer);
227+
var cases = new (GameObject Prefab, LogLevel LogLevel, bool ExpectWarning)[]
228+
{
229+
(m_Prefab, LogLevel.Developer, false),
230+
(m_HybridPrefab, LogLevel.Normal, false),
231+
(m_HybridPrefab, LogLevel.Developer, true),
232+
};
233+
234+
var warnings = new List<string>();
235+
Application.LogCallback onLogMessage = (message, stackTrace, logType) =>
236+
{
237+
if (logType == LogType.Warning && message.Contains(NetworkObject.NotRegisteredWithoutSessionWarning))
238+
{
239+
warnings.Add(message);
240+
}
241+
};
242+
Application.logMessageReceived += onLogMessage;
243+
try
244+
{
245+
foreach (var testCase in cases)
246+
{
247+
warnings.Clear();
248+
networkManager.LogLevel = testCase.LogLevel;
249+
var instance = UnityEngine.Object.Instantiate(testCase.Prefab).GetComponent<NetworkObject>();
250+
instance.NetworkManagerOwner = networkManager;
251+
var instanceName = instance.name;
252+
var caseName = $"{instanceName}][{testCase.LogLevel}";
253+
254+
// Start, where the instance is registered, runs on the next frame.
255+
yield return null;
256+
UnityEngine.Object.Destroy(instance.gameObject);
257+
yield return null;
258+
259+
Assert.AreEqual(testCase.ExpectWarning ? 1 : 0, warnings.Count, $"[{caseName}] Unexpected number of not registered warnings!");
260+
if (testCase.ExpectWarning)
261+
{
262+
StringAssert.Contains(instanceName, warnings[0], $"[{caseName}] The warning does not name the instance!");
263+
}
264+
}
265+
}
266+
finally
267+
{
268+
Application.logMessageReceived -= onLogMessage;
269+
}
270+
}
271+
218272
/// <summary>
219273
/// Validates that an override with a hybrid source or target is ignored, with an error naming it.
220274
/// </summary>

0 commit comments

Comments
 (0)