This repository has been archived on 2025-04-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviourUpdater.cs
Unity Technologies 0581a42b70 com.unity.netcode.gameobjects@1.5.2
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com).

## [1.5.2] - 2023-07-24

### Added

### Fixed

- Fixed issue where `NetworkClient.OwnedObjects` was not returning any owned objects due to the `NetworkClient.IsConnected` not being properly set. (#2631)
- Fixed a crash when calling TrySetParent with a null Transform (#2625)
- Fixed issue where a `NetworkTransform` using full precision state updates was losing transform state updates when interpolation was enabled. (#2624)
- Fixed issue where `NetworkObject.SpawnWithObservers` was not being honored for late joining clients. (#2623)
- Fixed issue where invoking `NetworkManager.Shutdown` multiple times, depending upon the timing, could cause an exception. (#2622)
- Fixed issue where removing ownership would not notify the server that it gained ownership. This also resolves the issue where an owner authoritative NetworkTransform would not properly initialize upon removing ownership from a remote client. (#2618)
- Fixed ILPP issues when using CoreCLR and for certain dedicated server builds. (#2614)
- Fixed an ILPP compile error when creating a generic NetworkBehaviour singleton with a static T instance. (#2603)

### Changed
2023-07-24 00:00:00 +00:00

132 lines
5.3 KiB
C#

using System.Collections.Generic;
using Unity.Profiling;
namespace Unity.Netcode
{
/// <summary>
/// An helper class that helps NetworkManager update NetworkBehaviours and replicate them down to connected clients.
/// </summary>
public class NetworkBehaviourUpdater
{
private NetworkManager m_NetworkManager;
private NetworkConnectionManager m_ConnectionManager;
private HashSet<NetworkObject> m_DirtyNetworkObjects = new HashSet<NetworkObject>();
#if DEVELOPMENT_BUILD || UNITY_EDITOR
private ProfilerMarker m_NetworkBehaviourUpdate = new ProfilerMarker($"{nameof(NetworkBehaviour)}.{nameof(NetworkBehaviourUpdate)}");
#endif
internal void AddForUpdate(NetworkObject networkObject)
{
m_DirtyNetworkObjects.Add(networkObject);
}
internal void NetworkBehaviourUpdate()
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
m_NetworkBehaviourUpdate.Begin();
#endif
try
{
// NetworkObject references can become null, when hidden or despawned. Once NUll, there is no point
// trying to process them, even if they were previously marked as dirty.
m_DirtyNetworkObjects.RemoveWhere((sobj) => sobj == null);
if (m_ConnectionManager.LocalClient.IsServer)
{
foreach (var dirtyObj in m_DirtyNetworkObjects)
{
for (int k = 0; k < dirtyObj.ChildNetworkBehaviours.Count; k++)
{
dirtyObj.ChildNetworkBehaviours[k].PreVariableUpdate();
}
for (int i = 0; i < m_ConnectionManager.ConnectedClientsList.Count; i++)
{
var client = m_ConnectionManager.ConnectedClientsList[i];
if (dirtyObj.IsNetworkVisibleTo(client.ClientId))
{
// Sync just the variables for just the objects this client sees
for (int k = 0; k < dirtyObj.ChildNetworkBehaviours.Count; k++)
{
dirtyObj.ChildNetworkBehaviours[k].VariableUpdate(client.ClientId);
}
}
}
}
}
else
{
// when client updates the server, it tells it about all its objects
foreach (var sobj in m_DirtyNetworkObjects)
{
if (sobj.IsOwner)
{
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
{
sobj.ChildNetworkBehaviours[k].PreVariableUpdate();
}
for (int k = 0; k < sobj.ChildNetworkBehaviours.Count; k++)
{
sobj.ChildNetworkBehaviours[k].VariableUpdate(NetworkManager.ServerClientId);
}
}
}
}
foreach (var dirtyObj in m_DirtyNetworkObjects)
{
for (int k = 0; k < dirtyObj.ChildNetworkBehaviours.Count; k++)
{
var behaviour = dirtyObj.ChildNetworkBehaviours[k];
for (int i = 0; i < behaviour.NetworkVariableFields.Count; i++)
{
if (behaviour.NetworkVariableFields[i].IsDirty() &&
!behaviour.NetworkVariableIndexesToResetSet.Contains(i))
{
behaviour.NetworkVariableIndexesToResetSet.Add(i);
behaviour.NetworkVariableIndexesToReset.Add(i);
}
}
}
}
// Now, reset all the no-longer-dirty variables
foreach (var dirtyobj in m_DirtyNetworkObjects)
{
dirtyobj.PostNetworkVariableWrite();
}
m_DirtyNetworkObjects.Clear();
}
finally
{
#if DEVELOPMENT_BUILD || UNITY_EDITOR
m_NetworkBehaviourUpdate.End();
#endif
}
}
internal void Initialize(NetworkManager networkManager)
{
m_NetworkManager = networkManager;
m_ConnectionManager = networkManager.ConnectionManager;
m_NetworkManager.NetworkTickSystem.Tick += NetworkBehaviourUpdater_Tick;
}
internal void Shutdown()
{
m_NetworkManager.NetworkTickSystem.Tick -= NetworkBehaviourUpdater_Tick;
}
// Order of operations requires NetworkVariable updates first then showing NetworkObjects
private void NetworkBehaviourUpdater_Tick()
{
// First update NetworkVariables
NetworkBehaviourUpdate();
// Then show any NetworkObjects queued to be made visible/shown
m_NetworkManager.SpawnManager.HandleNetworkObjectShow();
}
}
}