Skip to content

Commit 3190354

Browse files
Merge branch 'develop' into experimental/ngo-and-n4e
2 parents 2973bb9 + 706c6b4 commit 3190354

11 files changed

Lines changed: 559 additions & 90 deletions

File tree

.github/CODEOWNERS

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ Metrics/ @Unity-Technologies/multiplayer-tools
77
/com.unity.netcode.gameobjects/Runtime/Transports/ @Unity-Technologies/multiplayer-server
88
/com.unity.netcode.gameobjects/Tests/Editor/Transports/ @Unity-Technologies/multiplayer-server
99
/com.unity.netcode.gameobjects/Tests/Runtime/Transports/ @Unity-Technologies/multiplayer-server
10-
*.asmdef @ThusSpokeNomad
11-
package.json @ThusSpokeNomad
12-
AssemblyInfo.cs @ThusSpokeNomad
13-
.editorconfig @ThusSpokeNomad
14-
.gitignore @ThusSpokeNomad
15-
.github/ @ThusSpokeNomad @lpmaurice @ashwinimurt
16-
.yamato/ @ThusSpokeNomad @lpmaurice @ashwinimurt
10+
*.asmdef @chrispope @tylerunity
11+
package.json @chrispope @tylerunity
12+
AssemblyInfo.cs @chrispope @tylerunity
13+
.editorconfig @chrispope @tylerunity
14+
.gitignore @chrispope @tylerunity
15+
.github/ @chrispope @tylerunity
16+
.yamato/ @chrispope @tylerunity

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,16 @@ Additional documentation and release notes are available at [Multiplayer Documen
1010

1111
### Added
1212

13+
- Added `NetworkObject.SpawnWithObservers` property (default is true) that when set to false will spawn a `NetworkObject` with no observers and will not be spawned on any client until `NetworkObject.NetworkShow` is invoked. (#2568)
14+
1315
### Fixed
1416

17+
- Fixed warning "Runtime Network Prefabs was not empty at initialization time." being erroneously logged when no runtime network prefabs had been added (#2565)
1518
- Fixed issue where some temporary debug console logging was left in a merged PR. (#2562)
1619
- Fixed the "Generate Default Network Prefabs List" setting not loading correctly and always reverting to being checked. (#2545)
20+
- Fixed issue where users could not use NetworkSceneManager.VerifySceneBeforeLoading to exclude runtime generated scenes from client synchronization. (#2550)
1721
- Fixed missing value on `NetworkListEvent` for `EventType.RemoveAt` events. (#2542,#2543)
22+
- Fixed issue where parenting a NetworkTransform under a transform with a scale other than Vector3.one would result in incorrect values on non-authoritative instances. (#2538)
1823
- Fixed issue where a server would include scene migrated and then despawned NetworkObjects to a client that was being synchronized. (#2532)
1924
- Fixed the inspector throwing exceptions when attempting to render `NetworkVariable`s of enum types. (#2529)
2025
- Making a `NetworkVariable` with an `INetworkSerializable` type that doesn't meet the `new()` constraint will now create a compile-time error instead of an editor crash (#2528)
@@ -27,6 +32,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
2732

2833
## Changed
2934

35+
- Adding network prefabs before NetworkManager initialization is now supported. (#2565)
3036
- Connecting clients being synchronized now switch to the server's active scene before spawning and synchronizing NetworkObjects. (#2532)
3137
- Updated `UnityTransport` dependency on `com.unity.transport` to 1.3.4. (#2533)
3238
- Improved performance of NetworkBehaviour initialization by replacing reflection when initializing NetworkVariables with compile-time code generation, which should help reduce hitching during additive scene loads. (#2522)

com.unity.netcode.gameobjects/Components/NetworkTransform.cs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2392,16 +2392,6 @@ public override void OnNetworkSpawn()
23922392
m_CachedNetworkManager = NetworkManager;
23932393

23942394
Initialize();
2395-
// This assures the initial spawning of the object synchronizes all connected clients
2396-
// with the current transform values. This should not be placed within Initialize since
2397-
// that can be invoked when ownership changes.
2398-
if (CanCommitToTransform)
2399-
{
2400-
var currentPosition = GetSpaceRelativePosition();
2401-
var currentRotation = GetSpaceRelativeRotation();
2402-
// Teleport to current position
2403-
SetStateInternal(currentPosition, currentRotation, transform.localScale, true);
2404-
}
24052395
}
24062396

24072397
/// <inheritdoc/>
@@ -2472,6 +2462,7 @@ protected void Initialize()
24722462
CanCommitToTransform = IsServerAuthoritative() ? IsServer : IsOwner;
24732463
var replicatedState = ReplicatedNetworkState;
24742464
var currentPosition = GetSpaceRelativePosition();
2465+
var currentRotation = GetSpaceRelativeRotation();
24752466

24762467
if (CanCommitToTransform)
24772468
{
@@ -2483,6 +2474,9 @@ protected void Initialize()
24832474
// Authority only updates once per network tick
24842475
NetworkManager.NetworkTickSystem.Tick -= NetworkTickSystem_Tick;
24852476
NetworkManager.NetworkTickSystem.Tick += NetworkTickSystem_Tick;
2477+
2478+
// Teleport to current position
2479+
SetStateInternal(currentPosition, currentRotation, transform.localScale, true);
24862480
}
24872481
else
24882482
{
@@ -2494,15 +2488,42 @@ protected void Initialize()
24942488
NetworkManager.NetworkTickSystem.Tick -= NetworkTickSystem_Tick;
24952489

24962490
ResetInterpolatedStateToCurrentAuthoritativeState();
2497-
m_CurrentPosition = GetSpaceRelativePosition();
2491+
m_CurrentPosition = currentPosition;
24982492
m_CurrentScale = transform.localScale;
2499-
m_CurrentRotation = GetSpaceRelativeRotation();
2493+
m_CurrentRotation = currentRotation;
25002494

25012495
}
25022496

25032497
OnInitialize(ref replicatedState);
25042498
}
25052499

2500+
/// <inheritdoc/>
2501+
/// <remarks>
2502+
/// When a parent changes, non-authoritative instances should:
2503+
/// - Apply the resultant position, rotation, and scale from the parenting action.
2504+
/// - Clear interpolators (even if not enabled on this frame)
2505+
/// - Reset the interpolators to the position, rotation, and scale resultant values.
2506+
/// This prevents interpolation visual anomalies and issues during initial synchronization
2507+
/// </remarks>
2508+
public override void OnNetworkObjectParentChanged(NetworkObject parentNetworkObject)
2509+
{
2510+
// Only if we are not authority
2511+
if (!CanCommitToTransform)
2512+
{
2513+
m_CurrentPosition = GetSpaceRelativePosition();
2514+
m_CurrentRotation = GetSpaceRelativeRotation();
2515+
m_CurrentScale = GetScale();
2516+
m_ScaleInterpolator.Clear();
2517+
m_PositionInterpolator.Clear();
2518+
m_RotationInterpolator.Clear();
2519+
var tempTime = new NetworkTime(NetworkManager.NetworkConfig.TickRate, NetworkManager.ServerTime.Tick).Time;
2520+
UpdatePositionInterpolator(m_CurrentPosition, tempTime, true);
2521+
m_ScaleInterpolator.ResetTo(m_CurrentScale, tempTime);
2522+
m_RotationInterpolator.ResetTo(m_CurrentRotation, tempTime);
2523+
}
2524+
base.OnNetworkObjectParentChanged(parentNetworkObject);
2525+
}
2526+
25062527
/// <summary>
25072528
/// Directly sets a state on the authoritative transform.
25082529
/// Owner clients can directly set the state on a server authoritative transform
@@ -2656,6 +2677,12 @@ protected virtual void Update()
26562677
}
26572678
}
26582679

2680+
// If we have not received any additional state updates since the very
2681+
// initial synchronization, then exit early.
2682+
if (m_LocalAuthoritativeNetworkState.IsSynchronizing)
2683+
{
2684+
return;
2685+
}
26592686
// Apply the current authoritative state
26602687
ApplyAuthoritativeState();
26612688
}

com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,15 @@ public class NetworkPrefabs
3838
[NonSerialized]
3939
private List<NetworkPrefab> m_Prefabs = new List<NetworkPrefab>();
4040

41+
[NonSerialized]
42+
private List<NetworkPrefab> m_RuntimeAddedPrefabs = new List<NetworkPrefab>();
43+
4144
private void AddTriggeredByNetworkPrefabList(NetworkPrefab networkPrefab)
4245
{
4346
if (AddPrefabRegistration(networkPrefab))
4447
{
48+
// Don't add this to m_RuntimeAddedPrefabs
49+
// This prefab is now in the PrefabList, so if we shutdown and initialize again, we'll pick it up from there.
4550
m_Prefabs.Add(networkPrefab);
4651
}
4752
}
@@ -67,8 +72,6 @@ internal void Shutdown()
6772
list.OnAdd -= AddTriggeredByNetworkPrefabList;
6873
list.OnRemove -= RemoveTriggeredByNetworkPrefabList;
6974
}
70-
71-
NetworkPrefabsLists.Clear();
7275
}
7376

7477
/// <summary>
@@ -77,13 +80,7 @@ internal void Shutdown()
7780
/// </summary>
7881
public void Initialize(bool warnInvalid = true)
7982
{
80-
if (NetworkPrefabsLists.Count != 0 && m_Prefabs.Count > 0)
81-
{
82-
NetworkLog.LogWarning("Runtime Network Prefabs was not empty at initialization time. Network " +
83-
"Prefab registrations made before initialization will be replaced by NetworkPrefabsList.");
84-
m_Prefabs.Clear();
85-
}
86-
83+
m_Prefabs.Clear();
8784
foreach (var list in NetworkPrefabsLists)
8885
{
8986
list.OnAdd += AddTriggeredByNetworkPrefabList;
@@ -93,7 +90,7 @@ public void Initialize(bool warnInvalid = true)
9390
NetworkPrefabOverrideLinks.Clear();
9491
OverrideToNetworkPrefab.Clear();
9592

96-
var prefabs = NetworkPrefabsLists.Count != 0 ? new List<NetworkPrefab>() : m_Prefabs;
93+
var prefabs = new List<NetworkPrefab>();
9794

9895
if (NetworkPrefabsLists.Count != 0)
9996
{
@@ -126,6 +123,18 @@ public void Initialize(bool warnInvalid = true)
126123
}
127124
}
128125

126+
foreach (var networkPrefab in m_RuntimeAddedPrefabs)
127+
{
128+
if (AddPrefabRegistration(networkPrefab))
129+
{
130+
m_Prefabs.Add(networkPrefab);
131+
}
132+
else
133+
{
134+
removeList?.Add(networkPrefab);
135+
}
136+
}
137+
129138
// Clear out anything that is invalid or not used
130139
if (removeList?.Count > 0)
131140
{
@@ -152,6 +161,7 @@ public bool Add(NetworkPrefab networkPrefab)
152161
if (AddPrefabRegistration(networkPrefab))
153162
{
154163
m_Prefabs.Add(networkPrefab);
164+
m_RuntimeAddedPrefabs.Add(networkPrefab);
155165
return true;
156166
}
157167

@@ -175,6 +185,7 @@ public void Remove(NetworkPrefab prefab)
175185
}
176186

177187
m_Prefabs.Remove(prefab);
188+
m_RuntimeAddedPrefabs.Remove(prefab);
178189
OverrideToNetworkPrefab.Remove(prefab.TargetPrefabGlobalObjectIdHash);
179190
NetworkPrefabOverrideLinks.Remove(prefab.SourcePrefabGlobalObjectIdHash);
180191
}
@@ -203,6 +214,15 @@ public void Remove(GameObject prefab)
203214
return;
204215
}
205216
}
217+
218+
for (int i = 0; i < m_RuntimeAddedPrefabs.Count; i++)
219+
{
220+
if (m_RuntimeAddedPrefabs[i].Prefab == prefab)
221+
{
222+
Remove(m_RuntimeAddedPrefabs[i]);
223+
return;
224+
}
225+
}
206226
}
207227

208228
/// <summary>

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ internal void GenerateGlobalObjectIdHash()
188188
/// </remarks>
189189
public Action OnMigratedToNewScene;
190190

191+
/// <summary>
192+
/// When set to false, the NetworkObject will be spawned with no observers initially (other than the server)
193+
/// </summary>
194+
[Tooltip("When false, the NetworkObject will spawn with no observers initially. (default is true)")]
195+
public bool SpawnWithObservers = true;
196+
191197
/// <summary>
192198
/// Delegate type for checking visibility
193199
/// </summary>

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -786,9 +786,18 @@ private void SceneManager_ActiveSceneChanged(Scene current, Scene next)
786786
/// <returns>true (Valid) or false (Invalid)</returns>
787787
internal bool ValidateSceneBeforeLoading(uint sceneHash, LoadSceneMode loadSceneMode)
788788
{
789-
var validated = true;
790789
var sceneName = SceneNameFromHash(sceneHash);
791790
var sceneIndex = SceneUtility.GetBuildIndexByScenePath(sceneName);
791+
return ValidateSceneBeforeLoading(sceneIndex, sceneName, loadSceneMode);
792+
}
793+
794+
/// <summary>
795+
/// Overloaded version that is invoked by <see cref="ValidateSceneBeforeLoading"/> and <see cref="SynchronizeNetworkObjects"/>.
796+
/// This specifically is to allow runtime generated scenes to be excluded by the server during synchronization.
797+
/// </summary>
798+
internal bool ValidateSceneBeforeLoading(int sceneIndex, string sceneName, LoadSceneMode loadSceneMode)
799+
{
800+
var validated = true;
792801
if (VerifySceneBeforeLoading != null)
793802
{
794803
validated = VerifySceneBeforeLoading.Invoke(sceneIndex, sceneName, loadSceneMode);
@@ -1744,24 +1753,22 @@ internal void SynchronizeNetworkObjects(ulong clientId)
17441753
continue;
17451754
}
17461755

1747-
var sceneHash = SceneHashFromNameOrPath(scene.path);
1748-
17491756
// This would depend upon whether we are additive or not
17501757
// If we are the base scene, then we set the root scene index;
17511758
if (activeScene == scene)
17521759
{
1753-
if (!ValidateSceneBeforeLoading(sceneHash, sceneEventData.LoadSceneMode))
1760+
if (!ValidateSceneBeforeLoading(scene.buildIndex, scene.name, sceneEventData.LoadSceneMode))
17541761
{
17551762
continue;
17561763
}
1757-
sceneEventData.SceneHash = sceneHash;
1764+
sceneEventData.SceneHash = SceneHashFromNameOrPath(scene.path);
17581765
sceneEventData.SceneHandle = scene.handle;
17591766
}
1760-
else if (!ValidateSceneBeforeLoading(sceneHash, LoadSceneMode.Additive))
1767+
else if (!ValidateSceneBeforeLoading(scene.buildIndex, scene.name, LoadSceneMode.Additive))
17611768
{
17621769
continue;
17631770
}
1764-
sceneEventData.AddSceneToSynchronize(sceneHash, scene.handle);
1771+
sceneEventData.AddSceneToSynchronize(SceneHashFromNameOrPath(scene.path), scene.handle);
17651772
}
17661773

17671774
sceneEventData.AddSpawnedNetworkObjects();

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,8 +617,10 @@ private void SpawnNetworkObjectLocallyCommon(NetworkObject networkObject, ulong
617617
}
618618
}
619619

620-
if (NetworkManager.IsServer)
620+
// If we are the server and should spawn with observers
621+
if (NetworkManager.IsServer && networkObject.SpawnWithObservers)
621622
{
623+
// Add client observers
622624
for (int i = 0; i < NetworkManager.ConnectedClientsList.Count; i++)
623625
{
624626
if (networkObject.CheckObjectVisibility == null || networkObject.CheckObjectVisibility(NetworkManager.ConnectedClientsList[i].ClientId))

0 commit comments

Comments
 (0)