com.unity.netcode.gameobjects@1.2.0

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.2.0] - 2022-11-21

### Added

- Added protected method `NetworkBehaviour.OnSynchronize` which is invoked during the initial `NetworkObject` synchronization process. This provides users the ability to include custom serialization information that will be applied to the `NetworkBehaviour` prior to the `NetworkObject` being spawned. (#2298)
- Added support for different versions of the SDK to talk to each other in circumstances where changes permit it. Starting with this version and into future versions, patch versions should be compatible as long as the minor version is the same. (#2290)
- Added `NetworkObject` auto-add helper and Multiplayer Tools install reminder settings to Project Settings. (#2285)
- Added `public string DisconnectReason` getter to `NetworkManager` and `string Reason` to `ConnectionApprovalResponse`. Allows connection approval to communicate back a reason. Also added `public void DisconnectClient(ulong clientId, string reason)` allowing setting a disconnection reason, when explicitly disconnecting a client. (#2280)

### Changed

- Changed 3rd-party `XXHash` (32 & 64) implementation with an in-house reimplementation (#2310)
- When `NetworkConfig.EnsureNetworkVariableLengthSafety` is disabled `NetworkVariable` fields do not write the additional `ushort` size value (_which helps to reduce the total synchronization message size_), but when enabled it still writes the additional `ushort` value. (#2298)
- Optimized bandwidth usage by encoding most integer fields using variable-length encoding. (#2276)

### Fixed

- Fixed issue where `NetworkTransform` components nested under a parent with a `NetworkObject` component  (i.e. network prefab) would not have their associated `GameObject`'s transform synchronized. (#2298)
- Fixed issue where `NetworkObject`s that failed to instantiate could cause the entire synchronization pipeline to be disrupted/halted for a connecting client. (#2298)
- Fixed issue where in-scene placed `NetworkObject`s nested under a `GameObject` would be added to the orphaned children list causing continual console warning log messages. (#2298)
- Custom messages are now properly received by the local client when they're sent while running in host mode. (#2296)
- Fixed issue where the host would receive more than one event completed notification when loading or unloading a scene only when no clients were connected. (#2292)
- Fixed an issue in `UnityTransport` where an error would be logged if the 'Use Encryption' flag was enabled with a Relay configuration that used a secure protocol. (#2289)
- Fixed issue where in-scene placed `NetworkObjects` were not honoring the `AutoObjectParentSync` property. (#2281)
- Fixed the issue where `NetworkManager.OnClientConnectedCallback` was being invoked before in-scene placed `NetworkObject`s had been spawned when starting `NetworkManager` as a host. (#2277)
- Creating a `FastBufferReader` with `Allocator.None` will not result in extra memory being allocated for the buffer (since it's owned externally in that scenario). (#2265)

### Removed

- Removed the `NetworkObject` auto-add and Multiplayer Tools install reminder settings from the Menu interface. (#2285)
This commit is contained in:
Unity Technologies
2022-11-21 00:00:00 +00:00
parent 1e7078c160
commit fe02ca682e
96 changed files with 4522 additions and 2088 deletions

View File

@@ -86,6 +86,12 @@ namespace Unity.Netcode
private bool m_ShuttingDown;
private bool m_StopProcessingMessages;
/// <summary>
/// When disconnected from the server, the server may send a reason. If a reason was sent, this property will
/// tell client code what the reason was. It should be queried after the OnClientDisconnectCallback is called
/// </summary>
public string DisconnectReason { get; internal set; }
private class NetworkManagerHooks : INetworkHooks
{
private NetworkManager m_NetworkManager;
@@ -443,6 +449,12 @@ namespace Unity.Netcode
/// If the Approval decision cannot be made immediately, the client code can set Pending to true, keep a reference to the ConnectionApprovalResponse object and write to it later. Client code must exercise care to setting all the members to the value it wants before marking Pending to false, to indicate completion. If the field is set as Pending = true, we'll monitor the object until it gets set to not pending anymore and use the parameters then.
/// </summary>
public bool Pending;
/// <summary>
/// Optional reason. If Approved is false, this reason will be sent to the client so they know why they
/// were not approved.
/// </summary>
public string Reason;
}
/// <summary>
@@ -889,6 +901,7 @@ namespace Unity.Netcode
return;
}
DisconnectReason = string.Empty;
IsApproved = false;
ComponentFactory.SetDefaults();
@@ -1181,6 +1194,11 @@ namespace Unity.Netcode
SpawnManager.ServerSpawnSceneObjectsOnStartSweep();
// This assures that any in-scene placed NetworkObject is spawned and
// any associated NetworkBehaviours' netcode related properties are
// set prior to invoking OnClientConnected.
InvokeOnClientConnectedCallback(LocalClientId);
OnServerStarted?.Invoke();
return true;
@@ -1341,6 +1359,7 @@ namespace Unity.Netcode
private void DisconnectRemoteClient(ulong clientId)
{
var transportId = ClientIdToTransportId(clientId);
MessagingSystem.ProcessSendQueues();
NetworkConfig.NetworkTransport.DisconnectRemoteClient(transportId);
}
@@ -1421,7 +1440,7 @@ namespace Unity.Netcode
}
}
if (IsClient && IsConnectedClient)
if (IsClient && IsListening)
{
// Client only, send disconnect to server
NetworkConfig.NetworkTransport.DisconnectLocalClient();
@@ -1579,6 +1598,7 @@ namespace Unity.Netcode
} while (IsListening && networkEvent != NetworkEvent.Nothing);
MessagingSystem.ProcessIncomingMessageQueue();
MessagingSystem.CleanupDisconnectedClients();
#if DEVELOPMENT_BUILD || UNITY_EDITOR
s_TransportPoll.End();
@@ -1660,7 +1680,23 @@ namespace Unity.Netcode
ShouldSendConnectionData = NetworkConfig.ConnectionApproval,
ConnectionData = NetworkConfig.ConnectionData
};
message.MessageVersions = new NativeArray<MessageVersionData>(MessagingSystem.MessageHandlers.Length, Allocator.Temp);
for (int index = 0; index < MessagingSystem.MessageHandlers.Length; index++)
{
if (MessagingSystem.MessageTypes[index] != null)
{
var type = MessagingSystem.MessageTypes[index];
message.MessageVersions[index] = new MessageVersionData
{
Hash = XXHash.Hash32(type.FullName),
Version = MessagingSystem.GetLocalVersion(type)
};
}
}
SendMessage(ref message, NetworkDelivery.ReliableSequenced, ServerClientId);
message.MessageVersions.Dispose();
}
private IEnumerator ApprovalTimeout(ulong clientId)
@@ -1821,7 +1857,18 @@ namespace Unity.Netcode
NetworkLog.LogInfo($"Disconnect Event From {clientId}");
}
OnClientDisconnectCallback?.Invoke(clientId);
// Process the incoming message queue so that we get everything from the server disconnecting us
// or, if we are the server, so we got everything from that client.
MessagingSystem.ProcessIncomingMessageQueue();
try
{
OnClientDisconnectCallback?.Invoke(clientId);
}
catch (Exception exception)
{
Debug.LogException(exception);
}
if (IsServer)
{
@@ -1987,12 +2034,31 @@ namespace Unity.Netcode
/// </summary>
/// <param name="clientId">The ClientId to disconnect</param>
public void DisconnectClient(ulong clientId)
{
DisconnectClient(clientId, null);
}
/// <summary>
/// Disconnects the remote client.
/// </summary>
/// <param name="clientId">The ClientId to disconnect</param>
/// <param name="reason">Disconnection reason. If set, client will receive a DisconnectReasonMessage and have the
/// reason available in the NetworkManager.DisconnectReason property</param>
public void DisconnectClient(ulong clientId, string reason)
{
if (!IsServer)
{
throw new NotServerException($"Only server can disconnect remote clients. Please use `{nameof(Shutdown)}()` instead.");
}
if (!string.IsNullOrEmpty(reason))
{
var disconnectReason = new DisconnectReasonMessage();
disconnectReason.Reason = reason;
SendMessage(ref disconnectReason, NetworkDelivery.Reliable, clientId);
}
MessagingSystem.ProcessSendQueues();
OnClientDisconnectFromServer(clientId);
DisconnectRemoteClient(clientId);
}
@@ -2137,14 +2203,11 @@ namespace Unity.Netcode
// Generate a SceneObject for the player object to spawn
var sceneObject = new NetworkObject.SceneObject
{
Header = new NetworkObject.SceneObject.HeaderData
{
IsPlayerObject = true,
OwnerClientId = ownerClientId,
IsSceneObject = false,
HasTransform = true,
Hash = playerPrefabHash,
},
OwnerClientId = ownerClientId,
IsPlayerObject = true,
IsSceneObject = false,
HasTransform = true,
Hash = playerPrefabHash,
TargetClientId = ownerClientId,
Transform = new NetworkObject.SceneObject.TransformData
{
@@ -2184,22 +2247,23 @@ namespace Unity.Netcode
}
}
SendMessage(ref message, NetworkDelivery.ReliableFragmentedSequenced, ownerClientId);
message.MessageVersions = new NativeArray<MessageVersionData>(MessagingSystem.MessageHandlers.Length, Allocator.Temp);
for (int index = 0; index < MessagingSystem.MessageHandlers.Length; index++)
{
if (MessagingSystem.MessageTypes[index] != null)
{
var orderingMessage = new OrderingMessage
var type = MessagingSystem.MessageTypes[index];
message.MessageVersions[index] = new MessageVersionData
{
Order = index,
Hash = XXHash.Hash32(MessagingSystem.MessageTypes[index].FullName)
Hash = XXHash.Hash32(type.FullName),
Version = MessagingSystem.GetLocalVersion(type)
};
SendMessage(ref orderingMessage, NetworkDelivery.ReliableFragmentedSequenced, ownerClientId);
}
}
SendMessage(ref message, NetworkDelivery.ReliableFragmentedSequenced, ownerClientId);
message.MessageVersions.Dispose();
// If scene management is enabled, then let NetworkSceneManager handle the initial scene and NetworkObject synchronization
if (!NetworkConfig.EnableSceneManagement)
{
@@ -2214,7 +2278,6 @@ namespace Unity.Netcode
{
LocalClient = client;
SpawnManager.UpdateObservedNetworkObjects(ownerClientId);
InvokeOnClientConnectedCallback(ownerClientId);
}
if (!response.CreatePlayerObject || (response.PlayerPrefabHash == null && NetworkConfig.PlayerPrefab == null))
@@ -2227,6 +2290,15 @@ namespace Unity.Netcode
}
else
{
if (!string.IsNullOrEmpty(response.Reason))
{
var disconnectReason = new DisconnectReasonMessage();
disconnectReason.Reason = response.Reason;
SendMessage(ref disconnectReason, NetworkDelivery.Reliable, ownerClientId);
MessagingSystem.ProcessSendQueues();
}
PendingClients.Remove(ownerClientId);
DisconnectRemoteClient(ownerClientId);
}
@@ -2253,11 +2325,11 @@ namespace Unity.Netcode
{
ObjectInfo = ConnectedClients[clientId].PlayerObject.GetMessageSceneObject(clientPair.Key)
};
message.ObjectInfo.Header.Hash = playerPrefabHash;
message.ObjectInfo.Header.IsSceneObject = false;
message.ObjectInfo.Header.HasParent = false;
message.ObjectInfo.Header.IsPlayerObject = true;
message.ObjectInfo.Header.OwnerClientId = clientId;
message.ObjectInfo.Hash = playerPrefabHash;
message.ObjectInfo.IsSceneObject = false;
message.ObjectInfo.HasParent = false;
message.ObjectInfo.IsPlayerObject = true;
message.ObjectInfo.OwnerClientId = clientId;
var size = SendMessage(ref message, NetworkDelivery.ReliableFragmentedSequenced, clientPair.Key);
NetworkMetrics.TrackObjectSpawnSent(clientPair.Key, ConnectedClients[clientId].PlayerObject, size);
}