Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.12.0] - 2024-11-19

### Added

- Added `UnityTransport.GetEndpoint` method to provide a way to obtain `NetworkEndpoint` information of a connection via client identifier. (#3131)
- Added a static `NetworkManager.OnInstantiated` event notification to be able to track when a new `NetworkManager` instance has been instantiated. (#3089)
- Added a static `NetworkManager.OnDestroying` event notification to be able to track when an existing `NetworkManager` instance is being destroyed. (#3089)
- Added message size validation to named and unnamed message sending functions for better error messages. (#3043)
- Added "Check for NetworkObject Component" property to the Multiplayer->Netcode for GameObjects project settings. When disabled, this will bypass the in-editor `NetworkObject` check on `NetworkBehaviour` components. (#3034)

### Fixed

- Fixed issue where `NetworkList` properties on in-scene placed `NetworkObject`s could cause small memory leaks when entering playmode. (#3148)
- Fixed issue where a newly synchronizing client would be synchronized with the current `NetworkVariable` values always which could cause issues with collections if there were any pending state updates. Now, when initially synchronizing a client, if a `NetworkVariable` has a pending state update it will serialize the previously known value(s) to the synchronizing client so when the pending updates are sent they aren't duplicate values on the newly connected client side. (#3126)
- Fixed issue where changing ownership would mark every `NetworkVariable` dirty. Now, it will only mark any `NetworkVariable` with owner read permissions as dirty and will send/flush any pending updates to all clients prior to sending the change in ownership message.  (#3126)
- Fixed issue with `NetworkVariable` collections where transferring ownership to another client would not update the new owner's previous value to the most current value which could cause the last/previous added value to be detected as a change when adding or removing an entry (as long as the entry removed was not the last/previously added value).  (#3126)
- Fixed issue where a client (or server) with no write permissions for a `NetworkVariable` using a standard .NET collection type could still modify the collection which could cause various issues depending upon the modification and collection type.  (#3126)
- Fixed issue where `NetworkAnimator` would statically allocate write buffer space for `Animator` parameters that could cause a write error if the number of parameters exceeded the space allocated. (#3124)
- Fixed issue with the in-scene network prefab instance update menu tool where it was not properly updating scenes when invoked on the root prefab instance. (#3084)
- Fixed issue where `NetworkAnimator` would send updates to non-observer clients. (#3058)
- Fixed issue where an exception could occur when receiving a universal RPC for a `NetworkObject` that has been despawned. (#3055)
- Fixed issue where setting a prefab hash value during connection approval but not having a player prefab assigned could cause an exception when spawning a player. (#3046)
- Fixed issue where collections v2.2.x was not supported when using UTP v2.2.x within Unity v2022.3. (#3033)
- Fixed issue where the `NetworkSpawnManager.HandleNetworkObjectShow` could throw an exception if one of the `NetworkObject` components to show was destroyed during the same frame. (#3029)
- Fixed issue where the `NetworkManagerHelper` was continuing to check for hierarchy changes when in play mode. (#3027)

### Changed

- Changed `NetworkVariableDeltaMessage` so the server now forwards delta state updates (owner write permission based from a client) to other clients immediately as opposed to keeping a `NetworkVariable` or `NetworkList` dirty and processing them at the end of the frame or potentially on the next network tick. (#3126)
- The Debug Simulator section of the Unity Transport component will now be hidden if Unity Transport 2.0 or later is installed. It was already non-functional in that situation and users should instead use the more featureful [Network Simulator](https://docs-multiplayer.unity3d.com/tools/current/tools-network-simulator/) tool from the Multiplayer Tools package. (#3120)
  • Loading branch information
Unity Technologies committed Nov 19, 2024
1 parent c2664df commit 9c67175
Show file tree
Hide file tree
Showing 48 changed files with 2,576 additions and 457 deletions.
1 change: 1 addition & 0 deletions .signature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"timestamp":1734038821,"signature":"IRr6jlCcty11r8we1Ez4y7wx0e3FCIoANe7HGxeqQsSe+qAtXm7XbKkHoTpjhKgBTArN/+znpDoPZAGHy4oJnk7IgGDMorB5fPrG6hn4XRsaJgm1nSzV4KCmmMbV8EKO4NWqnlNIhtgO3Wvl9r+FvJlXOBZvvqExI0TGmBqM24rQT8KUns5JlVug1HcMt4CM5Gl7mbUOosxK4BGBhSyPi4xNNAqkWQnPlpK0cbF59zHNCphnctN5ANidsKjhUkLnCNAusukN5c99OMEsUakmJiCGcnzX0J0ynnR6XRGR6jPJbiK6h2kh+apQ6OuXP86aP0Aip2oZUBPRUw8nFf6YdlO/8MqASbLVryFqrUqryjfFFMzok+fZHPFyBmAuaV8X+heAXp7eKWWiRXuT7NeKD8gG6wo1QckT42i5tHJZPC1ovUEIAKqf747UmElQZWaLYIHHHmjCHV2lAAz8hZj1zo379u+epBeErG9Z71HqGrUHzLlEsGgCUOq9Vb+KXKyz","publicKey":"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQm9qQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FZOEFNSUlCaWdLQ0FZRUFzdUhXYUhsZ0I1cVF4ZEJjTlJKSAordHR4SmoxcVY1NTdvMlZaRE1XaXhYRVBkRTBEMVFkT1JIRXNSS1RscmplUXlERU83ZlNQS0ZwZ1A3MU5TTnJCCkFHM2NFSU45aHNQVDhOVmllZmdWem5QTkVMenFkVmdEbFhpb2VpUnV6OERKWFgvblpmU1JWKytwbk9ySTRibG4KS0twelJlNW14OTc1SjhxZ1FvRktKT0NNRlpHdkJMR2MxSzZZaEIzOHJFODZCZzgzbUovWjBEYkVmQjBxZm13cgo2ZDVFUXFsd0E5Y3JZT1YyV1VpWXprSnBLNmJZNzRZNmM1TmpBcEFKeGNiaTFOaDlRVEhUcU44N0ZtMDF0R1ZwCjVNd1pXSWZuYVRUemEvTGZLelR5U0pka0tldEZMVGdkYXpMYlpzUEE2aHBSK0FJRTJhc0tLTi84UUk1N3UzU2cKL2xyMnZKS1IvU2l5eEN1Q20vQWJkYnJMbXk0WjlSdm1jMGdpclA4T0lLQWxBRWZ2TzV5Z2hSKy8vd1RpTFlzUQp1SllDM0V2UE16ZGdKUzdGR2FscnFLZzlPTCsxVzROY05yNWdveVdSUUJ0cktKaWlTZEJVWmVxb0RvSUY5NHpCCndGbzJJT1JFdXFqcU51M3diMWZIM3p1dGdtalFra3IxVjJhd3hmcExLWlROQWdNQkFBRT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg"}
34 changes: 33 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,38 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

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

## [1.12.0] - 2024-11-19

### Added

- Added `UnityTransport.GetEndpoint` method to provide a way to obtain `NetworkEndpoint` information of a connection via client identifier. (#3131)
- Added a static `NetworkManager.OnInstantiated` event notification to be able to track when a new `NetworkManager` instance has been instantiated. (#3089)
- Added a static `NetworkManager.OnDestroying` event notification to be able to track when an existing `NetworkManager` instance is being destroyed. (#3089)
- Added message size validation to named and unnamed message sending functions for better error messages. (#3043)
- Added "Check for NetworkObject Component" property to the Multiplayer->Netcode for GameObjects project settings. When disabled, this will bypass the in-editor `NetworkObject` check on `NetworkBehaviour` components. (#3034)

### Fixed

- Fixed issue where `NetworkList` properties on in-scene placed `NetworkObject`s could cause small memory leaks when entering playmode. (#3148)
- Fixed issue where a newly synchronizing client would be synchronized with the current `NetworkVariable` values always which could cause issues with collections if there were any pending state updates. Now, when initially synchronizing a client, if a `NetworkVariable` has a pending state update it will serialize the previously known value(s) to the synchronizing client so when the pending updates are sent they aren't duplicate values on the newly connected client side. (#3126)
- Fixed issue where changing ownership would mark every `NetworkVariable` dirty. Now, it will only mark any `NetworkVariable` with owner read permissions as dirty and will send/flush any pending updates to all clients prior to sending the change in ownership message. (#3126)
- Fixed issue with `NetworkVariable` collections where transferring ownership to another client would not update the new owner's previous value to the most current value which could cause the last/previous added value to be detected as a change when adding or removing an entry (as long as the entry removed was not the last/previously added value). (#3126)
- Fixed issue where a client (or server) with no write permissions for a `NetworkVariable` using a standard .NET collection type could still modify the collection which could cause various issues depending upon the modification and collection type. (#3126)
- Fixed issue where `NetworkAnimator` would statically allocate write buffer space for `Animator` parameters that could cause a write error if the number of parameters exceeded the space allocated. (#3124)
- Fixed issue with the in-scene network prefab instance update menu tool where it was not properly updating scenes when invoked on the root prefab instance. (#3084)
- Fixed issue where `NetworkAnimator` would send updates to non-observer clients. (#3058)
- Fixed issue where an exception could occur when receiving a universal RPC for a `NetworkObject` that has been despawned. (#3055)
- Fixed issue where setting a prefab hash value during connection approval but not having a player prefab assigned could cause an exception when spawning a player. (#3046)
- Fixed issue where collections v2.2.x was not supported when using UTP v2.2.x within Unity v2022.3. (#3033)
- Fixed issue where the `NetworkSpawnManager.HandleNetworkObjectShow` could throw an exception if one of the `NetworkObject` components to show was destroyed during the same frame. (#3029)
- Fixed issue where the `NetworkManagerHelper` was continuing to check for hierarchy changes when in play mode. (#3027)

### Changed

- Changed `NetworkVariableDeltaMessage` so the server now forwards delta state updates (owner write permission based from a client) to other clients immediately as opposed to keeping a `NetworkVariable` or `NetworkList` dirty and processing them at the end of the frame or potentially on the next network tick. (#3126)
- The Debug Simulator section of the Unity Transport component will now be hidden if Unity Transport 2.0 or later is installed. It was already non-functional in that situation and users should instead use the more featureful [Network Simulator](https://docs-multiplayer.unity3d.com/tools/current/tools-network-simulator/) tool from the Multiplayer Tools package. (#3120)


## [1.11.0] - 2024-08-20

### Added
Expand Down Expand Up @@ -236,7 +268,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
- Fixed issue where invalid endpoint addresses were not being detected and returning false from NGO UnityTransport. (#2496)
- Fixed some errors that could occur if a connection is lost and the loss is detected when attempting to write to the socket. (#2495)

## Changed
### Changed

- Adding network prefabs before NetworkManager initialization is now supported. (#2565)
- Connecting clients being synchronized now switch to the server's active scene before spawning and synchronizing NetworkObjects. (#2532)
Expand Down
89 changes: 74 additions & 15 deletions Components/NetworkAnimator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,6 @@ protected virtual bool OnIsServerAuthoritative()
return true;
}

// Animators only support up to 32 parameters
// TODO: Look into making this a range limited property
private const int k_MaxAnimationParams = 32;

private int[] m_TransitionHash;
private int[] m_AnimationHash;
private float[] m_LayerWeights;
Expand All @@ -508,7 +504,7 @@ private unsafe struct AnimatorParamCache
}

// 128 bytes per Animator
private FastBufferWriter m_ParameterWriter = new FastBufferWriter(k_MaxAnimationParams * sizeof(float), Allocator.Persistent);
private FastBufferWriter m_ParameterWriter;

private NativeArray<AnimatorParamCache> m_CachedAnimatorParameters;

Expand Down Expand Up @@ -560,6 +556,14 @@ public override void OnDestroy()

private void Awake()
{
if (!m_Animator)
{
#if !UNITY_EDITOR
Debug.LogError($"{nameof(NetworkAnimator)} {name} does not have an {nameof(UnityEngine.Animator)} assigned to it. The {nameof(NetworkAnimator)} will not initialize properly.");
#endif
return;
}

int layers = m_Animator.layerCount;
// Initializing the below arrays for everyone handles an issue
// when running in owner authoritative mode and the owner changes.
Expand Down Expand Up @@ -589,6 +593,9 @@ private void Awake()
}
}

// The total initialization size calculated for the m_ParameterWriter write buffer.
var totalParameterSize = sizeof(uint);

// Build our reference parameter values to detect when they change
var parameters = m_Animator.parameters;
m_CachedAnimatorParameters = new NativeArray<AnimatorParamCache>(parameters.Length, Allocator.Persistent);
Expand Down Expand Up @@ -629,7 +636,37 @@ private void Awake()
}

m_CachedAnimatorParameters[i] = cacheParam;

// Calculate parameter sizes (index + type size)
switch (parameter.type)
{
case AnimatorControllerParameterType.Int:
{
totalParameterSize += sizeof(int) * 2;
break;
}
case AnimatorControllerParameterType.Bool:
case AnimatorControllerParameterType.Trigger:
{
// Bool is serialized to 1 byte
totalParameterSize += sizeof(int) + 1;
break;
}
case AnimatorControllerParameterType.Float:
{
totalParameterSize += sizeof(int) + sizeof(float);
break;
}
}
}

if (m_ParameterWriter.IsInitialized)
{
m_ParameterWriter.Dispose();
}

// Create our parameter write buffer for serialization
m_ParameterWriter = new FastBufferWriter(totalParameterSize, Allocator.Persistent);
}

/// <summary>
Expand Down Expand Up @@ -924,8 +961,14 @@ internal void CheckForAnimatorChanges()
{
// Just notify all remote clients and not the local server
m_ClientSendList.Clear();
m_ClientSendList.AddRange(NetworkManager.ConnectedClientsIds);
m_ClientSendList.Remove(NetworkManager.LocalClientId);
foreach (var clientId in NetworkManager.ConnectedClientsIds)
{
if (clientId == NetworkManager.LocalClientId || !NetworkObject.Observers.Contains(clientId))
{
continue;
}
m_ClientSendList.Add(clientId);
}
m_ClientRpcParams.Send.TargetClientIds = m_ClientSendList;
SendAnimStateClientRpc(m_AnimationMessage, m_ClientRpcParams);
}
Expand Down Expand Up @@ -1223,9 +1266,14 @@ private unsafe void SendParametersUpdateServerRpc(ParametersUpdateMessage parame
if (NetworkManager.ConnectedClientsIds.Count > (IsHost ? 2 : 1))
{
m_ClientSendList.Clear();
m_ClientSendList.AddRange(NetworkManager.ConnectedClientsIds);
m_ClientSendList.Remove(serverRpcParams.Receive.SenderClientId);
m_ClientSendList.Remove(NetworkManager.ServerClientId);
foreach (var clientId in NetworkManager.ConnectedClientsIds)
{
if (clientId == serverRpcParams.Receive.SenderClientId || clientId == NetworkManager.ServerClientId || !NetworkObject.Observers.Contains(clientId))
{
continue;
}
m_ClientSendList.Add(clientId);
}
m_ClientRpcParams.Send.TargetClientIds = m_ClientSendList;
m_NetworkAnimatorStateChangeHandler.SendParameterUpdate(parametersUpdate, m_ClientRpcParams);
}
Expand Down Expand Up @@ -1271,9 +1319,14 @@ private unsafe void SendAnimStateServerRpc(AnimationMessage animationMessage, Se
if (NetworkManager.ConnectedClientsIds.Count > (IsHost ? 2 : 1))
{
m_ClientSendList.Clear();
m_ClientSendList.AddRange(NetworkManager.ConnectedClientsIds);
m_ClientSendList.Remove(serverRpcParams.Receive.SenderClientId);
m_ClientSendList.Remove(NetworkManager.ServerClientId);
foreach (var clientId in NetworkManager.ConnectedClientsIds)
{
if (clientId == serverRpcParams.Receive.SenderClientId || clientId == NetworkManager.ServerClientId || !NetworkObject.Observers.Contains(clientId))
{
continue;
}
m_ClientSendList.Add(clientId);
}
m_ClientRpcParams.Send.TargetClientIds = m_ClientSendList;
m_NetworkAnimatorStateChangeHandler.SendAnimationUpdate(animationMessage, m_ClientRpcParams);
}
Expand Down Expand Up @@ -1322,8 +1375,14 @@ internal void SendAnimTriggerServerRpc(AnimationTriggerMessage animationTriggerM
InternalSetTrigger(animationTriggerMessage.Hash, animationTriggerMessage.IsTriggerSet);

m_ClientSendList.Clear();
m_ClientSendList.AddRange(NetworkManager.ConnectedClientsIds);
m_ClientSendList.Remove(NetworkManager.ServerClientId);
foreach (var clientId in NetworkManager.ConnectedClientsIds)
{
if (clientId == NetworkManager.ServerClientId || !NetworkObject.Observers.Contains(clientId))
{
continue;
}
m_ClientSendList.Add(clientId);
}

if (IsServerAuthoritative())
{
Expand Down
18 changes: 17 additions & 1 deletion Editor/Configuration/NetcodeForGameObjectsSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Unity.Netcode.Editor.Configuration
internal class NetcodeForGameObjectsEditorSettings
{
internal const string AutoAddNetworkObjectIfNoneExists = "AutoAdd-NetworkObject-When-None-Exist";
internal const string CheckForNetworkObject = "NetworkBehaviour-Check-For-NetworkObject";
internal const string InstallMultiplayerToolsTipDismissedPlayerPrefKey = "Netcode_Tip_InstallMPTools_Dismissed";

internal static int GetNetcodeInstallMultiplayerToolTips()
Expand All @@ -28,13 +29,28 @@ internal static bool GetAutoAddNetworkObjectSetting()
{
return EditorPrefs.GetBool(AutoAddNetworkObjectIfNoneExists);
}

// Default for this is false
return false;
}

internal static void SetAutoAddNetworkObjectSetting(bool autoAddSetting)
{
EditorPrefs.SetBool(AutoAddNetworkObjectIfNoneExists, autoAddSetting);
}

internal static bool GetCheckForNetworkObjectSetting()
{
if (EditorPrefs.HasKey(CheckForNetworkObject))
{
return EditorPrefs.GetBool(CheckForNetworkObject);
}
// Default for this is true
return true;
}

internal static void SetCheckForNetworkObjectSetting(bool checkForNetworkObject)
{
EditorPrefs.SetBool(CheckForNetworkObject, checkForNetworkObject);
}
}
}
22 changes: 19 additions & 3 deletions Editor/Configuration/NetcodeSettingsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ private static void OnDeactivate()

internal static NetcodeSettingsLabel NetworkObjectsSectionLabel;
internal static NetcodeSettingsToggle AutoAddNetworkObjectToggle;
internal static NetcodeSettingsToggle CheckForNetworkObjectToggle;
internal static NetcodeSettingsLabel MultiplayerToolsLabel;
internal static NetcodeSettingsToggle MultiplayerToolTipStatusToggle;

Expand All @@ -103,6 +104,11 @@ private static void CheckForInitialize()
AutoAddNetworkObjectToggle = new NetcodeSettingsToggle("Auto-Add NetworkObject Component", "When enabled, NetworkObject components are automatically added to GameObjects when NetworkBehaviour components are added first.", 20);
}

if (CheckForNetworkObjectToggle == null)
{
CheckForNetworkObjectToggle = new NetcodeSettingsToggle("Check for NetworkObject Component", "When disabled, the automatic check on NetworkBehaviours for an associated NetworkObject component will not be performed and Auto-Add NetworkObject Component will be disabled.", 20);
}

if (MultiplayerToolsLabel == null)
{
MultiplayerToolsLabel = new NetcodeSettingsLabel("Multiplayer Tools", 20);
Expand All @@ -120,6 +126,7 @@ private static void OnGuiHandler(string obj)
CheckForInitialize();

var autoAddNetworkObjectSetting = NetcodeForGameObjectsEditorSettings.GetAutoAddNetworkObjectSetting();
var checkForNetworkObjectSetting = NetcodeForGameObjectsEditorSettings.GetCheckForNetworkObjectSetting();
var multiplayerToolsTipStatus = NetcodeForGameObjectsEditorSettings.GetNetcodeInstallMultiplayerToolTips() == 0;
var settings = NetcodeForGameObjectsProjectSettings.instance;
var generateDefaultPrefabs = settings.GenerateDefaultNetworkPrefabs;
Expand All @@ -134,7 +141,12 @@ private static void OnGuiHandler(string obj)
{
GUILayout.BeginVertical("Box");
NetworkObjectsSectionLabel.DrawLabel();
autoAddNetworkObjectSetting = AutoAddNetworkObjectToggle.DrawToggle(autoAddNetworkObjectSetting);
autoAddNetworkObjectSetting = AutoAddNetworkObjectToggle.DrawToggle(autoAddNetworkObjectSetting, checkForNetworkObjectSetting);
checkForNetworkObjectSetting = CheckForNetworkObjectToggle.DrawToggle(checkForNetworkObjectSetting);
if (autoAddNetworkObjectSetting && !checkForNetworkObjectSetting)
{
autoAddNetworkObjectSetting = false;
}
GUILayout.EndVertical();

GUILayout.BeginVertical("Box");
Expand Down Expand Up @@ -184,6 +196,7 @@ private static void OnGuiHandler(string obj)
if (EditorGUI.EndChangeCheck())
{
NetcodeForGameObjectsEditorSettings.SetAutoAddNetworkObjectSetting(autoAddNetworkObjectSetting);
NetcodeForGameObjectsEditorSettings.SetCheckForNetworkObjectSetting(checkForNetworkObjectSetting);
NetcodeForGameObjectsEditorSettings.SetNetcodeInstallMultiplayerToolTips(multiplayerToolsTipStatus ? 0 : 1);
settings.GenerateDefaultNetworkPrefabs = generateDefaultPrefabs;
settings.TempNetworkPrefabsPath = networkPrefabsPath;
Expand Down Expand Up @@ -213,10 +226,13 @@ internal class NetcodeSettingsToggle : NetcodeGUISettings
{
private GUIContent m_ToggleContent;

public bool DrawToggle(bool currentSetting)
public bool DrawToggle(bool currentSetting, bool enabled = true)
{
EditorGUIUtility.labelWidth = m_LabelSize;
return EditorGUILayout.Toggle(m_ToggleContent, currentSetting, m_LayoutWidth);
GUI.enabled = enabled;
var returnValue = EditorGUILayout.Toggle(m_ToggleContent, currentSetting, m_LayoutWidth);
GUI.enabled = true;
return returnValue;
}

public NetcodeSettingsToggle(string labelText, string toolTip, float layoutOffset)
Expand Down
2 changes: 1 addition & 1 deletion Editor/Configuration/NetworkPrefabProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ bool ProcessDeletedAssets(string[] strings)

// Process the imported and deleted assets
var markDirty = ProcessImportedAssets(importedAssets);
markDirty &= ProcessDeletedAssets(deletedAssets);
markDirty |= ProcessDeletedAssets(deletedAssets);

if (markDirty)
{
Expand Down
Loading

0 comments on commit 9c67175

Please sign in to comment.