com.unity.netcode.gameobjects@1.0.0-pre.3

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.0.0-pre.3] - 2021-10-22

### Added

- ResetTrigger function to NetworkAnimator (#1327)

### Fixed

- Overflow exception when syncing Animator state. (#1327)
- Added `try`/`catch` around RPC calls, preventing exception from causing further RPC calls to fail (#1329)
- Fixed an issue where ServerClientId and LocalClientId could have the same value, causing potential confusion, and also fixed an issue with the UNet where the server could be identified with two different values, one of which might be the same as LocalClientId, and the other of which would not.(#1368)
- IL2CPP would not properly compile (#1359)
This commit is contained in:
Unity Technologies
2021-10-22 00:00:00 +00:00
parent 22d877d1b2
commit f5664b4cc1
14 changed files with 408 additions and 228 deletions

View File

@@ -6,7 +6,21 @@ 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). Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com).
## [1.0.0-pre.2] - 2020-12-20 ## [1.0.0-pre.3] - 2021-10-22
### Added
- ResetTrigger function to NetworkAnimator (#1327)
### Fixed
- Overflow exception when syncing Animator state. (#1327)
- Added `try`/`catch` around RPC calls, preventing exception from causing further RPC calls to fail (#1329)
- Fixed an issue where ServerClientId and LocalClientId could have the same value, causing potential confusion, and also fixed an issue with the UNet where the server could be identified with two different values, one of which might be the same as LocalClientId, and the other of which would not.(#1368)
- IL2CPP would not properly compile (#1359)
## [1.0.0-pre.2] - 2021-10-19
### Added ### Added
@@ -16,7 +30,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
- Updated label for `1.0.0-pre.1` changelog section - Updated label for `1.0.0-pre.1` changelog section
## [1.0.0-pre.1] - 2020-12-20 ## [1.0.0-pre.1] - 2021-10-19
### Added ### Added

View File

@@ -1,5 +1,6 @@
using Unity.Collections; using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe; using Unity.Collections.LowLevel.Unsafe;
using UnityEngine; using UnityEngine;
namespace Unity.Netcode.Components namespace Unity.Netcode.Components
@@ -38,11 +39,12 @@ namespace Unity.Netcode.Components
internal struct AnimationTriggerMessage : INetworkSerializable internal struct AnimationTriggerMessage : INetworkSerializable
{ {
public int Hash; public int Hash;
public bool Reset;
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{ {
serializer.SerializeValue(ref Hash); serializer.SerializeValue(ref Hash);
serializer.SerializeValue(ref Reset);
} }
} }
@@ -286,6 +288,12 @@ namespace Unity.Netcode.Components
return false; return false;
} }
/* $AS TODO: Right now we are not checking for changed values this is because
the read side of this function doesn't have similar logic which would cause
an overflow read because it doesn't know if the value is there or not. So
there needs to be logic to track which indexes changed in order for there
to be proper value change checking. Will revist in 1.1.0.
*/
private unsafe bool WriteParameters(FastBufferWriter writer, bool autoSend) private unsafe bool WriteParameters(FastBufferWriter writer, bool autoSend)
{ {
if (m_CachedAnimatorParameters == null) if (m_CachedAnimatorParameters == null)
@@ -308,12 +316,8 @@ namespace Unity.Netcode.Components
var valueInt = m_Animator.GetInteger(hash); var valueInt = m_Animator.GetInteger(hash);
fixed (void* value = cacheValue.Value) fixed (void* value = cacheValue.Value)
{ {
var oldValue = UnsafeUtility.AsRef<int>(value); UnsafeUtility.WriteArrayElement(value, 0, valueInt);
if (valueInt != oldValue) BytePacker.WriteValuePacked(writer, (uint)valueInt);
{
UnsafeUtility.WriteArrayElement(value, 0, valueInt);
BytePacker.WriteValuePacked(writer, (uint)valueInt);
}
} }
} }
else if (cacheValue.Type == AnimationParamEnumWrapper.AnimatorControllerParameterBool) else if (cacheValue.Type == AnimationParamEnumWrapper.AnimatorControllerParameterBool)
@@ -321,12 +325,8 @@ namespace Unity.Netcode.Components
var valueBool = m_Animator.GetBool(hash); var valueBool = m_Animator.GetBool(hash);
fixed (void* value = cacheValue.Value) fixed (void* value = cacheValue.Value)
{ {
var oldValue = UnsafeUtility.AsRef<bool>(value); UnsafeUtility.WriteArrayElement(value, 0, valueBool);
if (valueBool != oldValue) writer.WriteValueSafe(valueBool);
{
UnsafeUtility.WriteArrayElement(value, 0, valueBool);
writer.WriteValueSafe(valueBool);
}
} }
} }
else if (cacheValue.Type == AnimationParamEnumWrapper.AnimatorControllerParameterFloat) else if (cacheValue.Type == AnimationParamEnumWrapper.AnimatorControllerParameterFloat)
@@ -334,13 +334,9 @@ namespace Unity.Netcode.Components
var valueFloat = m_Animator.GetFloat(hash); var valueFloat = m_Animator.GetFloat(hash);
fixed (void* value = cacheValue.Value) fixed (void* value = cacheValue.Value)
{ {
var oldValue = UnsafeUtility.AsRef<float>(value);
if (valueFloat != oldValue)
{
UnsafeUtility.WriteArrayElement(value, 0, valueFloat);
writer.WriteValueSafe(valueFloat); UnsafeUtility.WriteArrayElement(value, 0, valueFloat);
} writer.WriteValueSafe(valueFloat);
} }
} }
} }
@@ -432,7 +428,14 @@ namespace Unity.Netcode.Components
[ClientRpc] [ClientRpc]
private void SendAnimTriggerClientRpc(AnimationTriggerMessage animSnapshot, ClientRpcParams clientRpcParams = default) private void SendAnimTriggerClientRpc(AnimationTriggerMessage animSnapshot, ClientRpcParams clientRpcParams = default)
{ {
m_Animator.SetTrigger(animSnapshot.Hash); if (animSnapshot.Reset)
{
m_Animator.ResetTrigger(animSnapshot.Hash);
}
else
{
m_Animator.SetTrigger(animSnapshot.Hash);
}
} }
public void SetTrigger(string triggerName) public void SetTrigger(string triggerName)
@@ -440,15 +443,26 @@ namespace Unity.Netcode.Components
SetTrigger(Animator.StringToHash(triggerName)); SetTrigger(Animator.StringToHash(triggerName));
} }
public void SetTrigger(int hash) public void SetTrigger(int hash, bool reset = false)
{ {
var animMsg = new AnimationTriggerMessage(); var animMsg = new AnimationTriggerMessage();
animMsg.Hash = hash; animMsg.Hash = hash;
animMsg.Reset = reset;
if (IsServer) if (IsServer)
{ {
SendAnimTriggerClientRpc(animMsg); SendAnimTriggerClientRpc(animMsg);
} }
} }
public void ResetTrigger(string triggerName)
{
ResetTrigger(Animator.StringToHash(triggerName));
}
public void ResetTrigger(int hash)
{
SetTrigger(hash, true);
}
} }
} }

View File

@@ -1127,6 +1127,11 @@ namespace Unity.Netcode.Editor.CodeGen
nhandler.Parameters.Add(new ParameterDefinition("rpcParams", ParameterAttributes.None, m_RpcParams_TypeRef)); nhandler.Parameters.Add(new ParameterDefinition("rpcParams", ParameterAttributes.None, m_RpcParams_TypeRef));
var processor = nhandler.Body.GetILProcessor(); var processor = nhandler.Body.GetILProcessor();
// begin Try/Catch
var tryStart = processor.Create(OpCodes.Nop);
processor.Append(tryStart);
var isServerRpc = rpcAttribute.AttributeType.FullName == CodeGenHelpers.ServerRpcAttribute_FullName; var isServerRpc = rpcAttribute.AttributeType.FullName == CodeGenHelpers.ServerRpcAttribute_FullName;
var requireOwnership = true; // default value MUST be = `ServerRpcAttribute.RequireOwnership` var requireOwnership = true; // default value MUST be = `ServerRpcAttribute.RequireOwnership`
foreach (var attrField in rpcAttribute.Fields) foreach (var attrField in rpcAttribute.Fields)
@@ -1303,7 +1308,54 @@ namespace Unity.Netcode.Editor.CodeGen
processor.Emit(OpCodes.Ldc_I4, (int)NetworkBehaviour.__RpcExecStage.None); processor.Emit(OpCodes.Ldc_I4, (int)NetworkBehaviour.__RpcExecStage.None);
processor.Emit(OpCodes.Stfld, m_NetworkBehaviour_rpc_exec_stage_FieldRef); processor.Emit(OpCodes.Stfld, m_NetworkBehaviour_rpc_exec_stage_FieldRef);
// pull in the Exception Module
var exception = m_MainModule.ImportReference(typeof(Exception));
// Get Exception.ToString()
var exp = m_MainModule.ImportReference(typeof(Exception).GetMethod("ToString", new Type[] { }));
// Get String.Format (This is equivalent to an interpolated string)
var stringFormat = m_MainModule.ImportReference(typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(object) }));
nhandler.Body.Variables.Add(new VariableDefinition(exception));
int exceptionVariableIndex = nhandler.Body.Variables.Count - 1;
//try ends/catch begins
var catchEnds = processor.Create(OpCodes.Nop);
processor.Emit(OpCodes.Leave, catchEnds);
// Load the Exception onto the stack
var catchStarts = processor.Create(OpCodes.Stloc, exceptionVariableIndex);
processor.Append(catchStarts);
// Load string for the error log that will be shown
processor.Emit(OpCodes.Ldstr, $"Unhandled RPC Exception:\n {{0}}");
processor.Emit(OpCodes.Ldloc, exceptionVariableIndex);
processor.Emit(OpCodes.Callvirt, exp);
processor.Emit(OpCodes.Call, stringFormat);
// Call Debug.LogError
processor.Emit(OpCodes.Call, m_Debug_LogError_MethodRef);
// reset NetworkBehaviour.__rpc_exec_stage = __RpcExecStage.None;
processor.Emit(OpCodes.Ldarg_0);
processor.Emit(OpCodes.Ldc_I4, (int)NetworkBehaviour.__RpcExecStage.None);
processor.Emit(OpCodes.Stfld, m_NetworkBehaviour_rpc_exec_stage_FieldRef);
// catch ends
processor.Append(catchEnds);
processor.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch)
{
CatchType = exception,
TryStart = tryStart,
TryEnd = catchStarts,
HandlerStart = catchStarts,
HandlerEnd = catchEnds
});
processor.Emit(OpCodes.Ret); processor.Emit(OpCodes.Ret);
return nhandler; return nhandler;
} }
} }

View File

@@ -149,14 +149,9 @@ namespace Unity.Netcode
public void Send(ulong clientId, NetworkDelivery delivery, FastBufferWriter batchData) public void Send(ulong clientId, NetworkDelivery delivery, FastBufferWriter batchData)
{ {
var sendBuffer = batchData.ToTempByteArray();
var length = batchData.Length; m_NetworkManager.NetworkConfig.NetworkTransport.Send(m_NetworkManager.ClientIdToTransportId(clientId), sendBuffer, delivery);
//TODO: Transport needs to have a way to send it data without copying and allocating here.
var bytes = batchData.ToArray();
var sendBuffer = new ArraySegment<byte>(bytes, 0, length);
m_NetworkManager.NetworkConfig.NetworkTransport.Send(clientId, sendBuffer, delivery);
} }
} }
@@ -228,10 +223,12 @@ namespace Unity.Netcode
public NetworkSceneManager SceneManager { get; private set; } public NetworkSceneManager SceneManager { get; private set; }
public readonly ulong ServerClientId = 0;
/// <summary> /// <summary>
/// Gets the networkId of the server /// Gets the networkId of the server
/// </summary> /// </summary>
public ulong ServerClientId => NetworkConfig.NetworkTransport?.ServerClientId ?? private ulong m_ServerTransportId => NetworkConfig.NetworkTransport?.ServerClientId ??
throw new NullReferenceException( throw new NullReferenceException(
$"The transport in the active {nameof(NetworkConfig)} is null"); $"The transport in the active {nameof(NetworkConfig)} is null");
@@ -248,6 +245,10 @@ namespace Unity.Netcode
private Dictionary<ulong, NetworkClient> m_ConnectedClients = new Dictionary<ulong, NetworkClient>(); private Dictionary<ulong, NetworkClient> m_ConnectedClients = new Dictionary<ulong, NetworkClient>();
private ulong m_NextClientId = 1;
private Dictionary<ulong, ulong> m_ClientIdToTransportIdMap = new Dictionary<ulong, ulong>();
private Dictionary<ulong, ulong> m_TransportIdToClientIdMap = new Dictionary<ulong, ulong>();
private List<NetworkClient> m_ConnectedClientsList = new List<NetworkClient>(); private List<NetworkClient> m_ConnectedClientsList = new List<NetworkClient>();
private List<ulong> m_ConnectedClientIds = new List<ulong>(); private List<ulong> m_ConnectedClientIds = new List<ulong>();
@@ -985,6 +986,12 @@ namespace Unity.Netcode
} }
} }
private void DisconnectRemoteClient(ulong clientId)
{
var transportId = ClientIdToTransportId(clientId);
NetworkConfig.NetworkTransport.DisconnectRemoteClient(transportId);
}
/// <summary> /// <summary>
/// Globally shuts down the library. /// Globally shuts down the library.
/// Disconnects clients if connected and stops server if running. /// Disconnects clients if connected and stops server if running.
@@ -1019,7 +1026,7 @@ namespace Unity.Netcode
continue; continue;
} }
NetworkConfig.NetworkTransport.DisconnectRemoteClient(pair.Key); DisconnectRemoteClient(pair.Key);
} }
} }
@@ -1033,7 +1040,7 @@ namespace Unity.Netcode
continue; continue;
} }
NetworkConfig.NetworkTransport.DisconnectRemoteClient(pair.Key); DisconnectRemoteClient(pair.Key);
} }
} }
} }
@@ -1103,6 +1110,9 @@ namespace Unity.Netcode
NetworkConfig?.NetworkTransport?.Shutdown(); NetworkConfig?.NetworkTransport?.Shutdown();
} }
m_ClientIdToTransportIdMap.Clear();
m_TransportIdToClientIdMap.Clear();
IsListening = false; IsListening = false;
} }
@@ -1229,14 +1239,30 @@ namespace Unity.Netcode
} }
} }
private ulong TransportIdToClientId(ulong transportId)
{
return transportId == m_ServerTransportId ? ServerClientId : m_TransportIdToClientIdMap[transportId];
}
private ulong ClientIdToTransportId(ulong clientId)
{
return clientId == ServerClientId ? m_ServerTransportId : m_ClientIdToTransportIdMap[clientId];
}
private void HandleRawTransportPoll(NetworkEvent networkEvent, ulong clientId, ArraySegment<byte> payload, float receiveTime) private void HandleRawTransportPoll(NetworkEvent networkEvent, ulong clientId, ArraySegment<byte> payload, float receiveTime)
{ {
var transportId = clientId;
switch (networkEvent) switch (networkEvent)
{ {
case NetworkEvent.Connect: case NetworkEvent.Connect:
#if DEVELOPMENT_BUILD || UNITY_EDITOR #if DEVELOPMENT_BUILD || UNITY_EDITOR
s_TransportConnect.Begin(); s_TransportConnect.Begin();
#endif #endif
clientId = m_NextClientId++;
m_ClientIdToTransportIdMap[clientId] = transportId;
m_TransportIdToClientIdMap[transportId] = clientId;
MessagingSystem.ClientConnected(clientId); MessagingSystem.ClientConnected(clientId);
if (IsServer) if (IsServer)
{ {
@@ -1275,6 +1301,8 @@ namespace Unity.Netcode
NetworkLog.LogInfo($"Incoming Data From {clientId}: {payload.Count} bytes"); NetworkLog.LogInfo($"Incoming Data From {clientId}: {payload.Count} bytes");
} }
clientId = TransportIdToClientId(clientId);
HandleIncomingData(clientId, payload, receiveTime); HandleIncomingData(clientId, payload, receiveTime);
break; break;
} }
@@ -1282,6 +1310,10 @@ namespace Unity.Netcode
#if DEVELOPMENT_BUILD || UNITY_EDITOR #if DEVELOPMENT_BUILD || UNITY_EDITOR
s_TransportDisconnect.Begin(); s_TransportDisconnect.Begin();
#endif #endif
clientId = TransportIdToClientId(clientId);
m_TransportIdToClientIdMap.Remove(transportId);
m_ClientIdToTransportIdMap.Remove(clientId);
if (NetworkLog.CurrentLogLevel <= LogLevel.Developer) if (NetworkLog.CurrentLogLevel <= LogLevel.Developer)
{ {
@@ -1405,8 +1437,7 @@ namespace Unity.Netcode
} }
OnClientDisconnectFromServer(clientId); OnClientDisconnectFromServer(clientId);
DisconnectRemoteClient(clientId);
NetworkConfig.NetworkTransport.DisconnectRemoteClient(clientId);
} }
private void OnClientDisconnectFromServer(ulong clientId) private void OnClientDisconnectFromServer(ulong clientId)
@@ -1580,7 +1611,7 @@ namespace Unity.Netcode
else else
{ {
PendingClients.Remove(ownerClientId); PendingClients.Remove(ownerClientId);
NetworkConfig.NetworkTransport.DisconnectRemoteClient(ownerClientId); DisconnectRemoteClient(ownerClientId);
} }
} }

View File

@@ -40,7 +40,7 @@ namespace Unity.Netcode
((UnnamedMessageDelegate)handler).Invoke(clientId, reader); ((UnnamedMessageDelegate)handler).Invoke(clientId, reader);
} }
} }
m_NetworkManager.NetworkMetrics.TrackUnnamedMessageReceived(clientId, reader.Length); m_NetworkManager.NetworkMetrics.TrackUnnamedMessageReceived(clientId, reader.Length + FastBufferWriter.GetWriteSize<MessageHeader>());
} }
/// <summary> /// <summary>
@@ -53,7 +53,6 @@ namespace Unity.Netcode
SendUnnamedMessage(m_NetworkManager.ConnectedClientsIds, messageBuffer, networkDelivery); SendUnnamedMessage(m_NetworkManager.ConnectedClientsIds, messageBuffer, networkDelivery);
} }
/// <summary> /// <summary>
/// Sends unnamed message to a list of clients /// Sends unnamed message to a list of clients
/// </summary> /// </summary>
@@ -118,7 +117,7 @@ namespace Unity.Netcode
internal void InvokeNamedMessage(ulong hash, ulong sender, FastBufferReader reader) internal void InvokeNamedMessage(ulong hash, ulong sender, FastBufferReader reader)
{ {
var bytesCount = reader.Length; var bytesCount = reader.Length + FastBufferWriter.GetWriteSize<MessageHeader>();
if (m_NetworkManager == null) if (m_NetworkManager == null)
{ {

View File

@@ -226,7 +226,7 @@ namespace Unity.Netcode
for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx) for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx)
{ {
m_Hooks[hookIdx].OnBeforeReceiveMessage(senderId, type, reader.Length); m_Hooks[hookIdx].OnBeforeReceiveMessage(senderId, type, reader.Length + FastBufferWriter.GetWriteSize<MessageHeader>());
} }
var handler = m_MessageHandlers[header.MessageType]; var handler = m_MessageHandlers[header.MessageType];
using (reader) using (reader)
@@ -247,7 +247,7 @@ namespace Unity.Netcode
} }
for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx) for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx)
{ {
m_Hooks[hookIdx].OnAfterReceiveMessage(senderId, type, reader.Length); m_Hooks[hookIdx].OnAfterReceiveMessage(senderId, type, reader.Length + FastBufferWriter.GetWriteSize<MessageHeader>());
} }
} }
@@ -310,8 +310,13 @@ namespace Unity.Netcode
where TMessageType : INetworkMessage where TMessageType : INetworkMessage
where TClientIdListType : IReadOnlyList<ulong> where TClientIdListType : IReadOnlyList<ulong>
{ {
if (clientIds.Count == 0)
{
return 0;
}
var maxSize = delivery == NetworkDelivery.ReliableFragmentedSequenced ? FRAGMENTED_MESSAGE_MAX_SIZE : NON_FRAGMENTED_MESSAGE_MAX_SIZE; var maxSize = delivery == NetworkDelivery.ReliableFragmentedSequenced ? FRAGMENTED_MESSAGE_MAX_SIZE : NON_FRAGMENTED_MESSAGE_MAX_SIZE;
var tmpSerializer = new FastBufferWriter(NON_FRAGMENTED_MESSAGE_MAX_SIZE - sizeof(MessageHeader), Allocator.Temp, maxSize - sizeof(MessageHeader)); var tmpSerializer = new FastBufferWriter(NON_FRAGMENTED_MESSAGE_MAX_SIZE - FastBufferWriter.GetWriteSize<MessageHeader>(), Allocator.Temp, maxSize - FastBufferWriter.GetWriteSize<MessageHeader>());
using (tmpSerializer) using (tmpSerializer)
{ {
message.Serialize(tmpSerializer); message.Serialize(tmpSerializer);
@@ -342,7 +347,7 @@ namespace Unity.Netcode
ref var lastQueueItem = ref sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1); ref var lastQueueItem = ref sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1);
if (lastQueueItem.NetworkDelivery != delivery || if (lastQueueItem.NetworkDelivery != delivery ||
lastQueueItem.Writer.MaxCapacity - lastQueueItem.Writer.Position lastQueueItem.Writer.MaxCapacity - lastQueueItem.Writer.Position
< tmpSerializer.Length + sizeof(MessageHeader)) < tmpSerializer.Length + FastBufferWriter.GetWriteSize<MessageHeader>())
{ {
sendQueueItem.Add(new SendQueueItem(delivery, NON_FRAGMENTED_MESSAGE_MAX_SIZE, Allocator.TempJob, sendQueueItem.Add(new SendQueueItem(delivery, NON_FRAGMENTED_MESSAGE_MAX_SIZE, Allocator.TempJob,
maxSize)); maxSize));
@@ -351,7 +356,7 @@ namespace Unity.Netcode
} }
ref var writeQueueItem = ref sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1); ref var writeQueueItem = ref sendQueueItem.GetUnsafeList()->ElementAt(sendQueueItem.Length - 1);
writeQueueItem.Writer.TryBeginWrite(sizeof(MessageHeader) + tmpSerializer.Length); writeQueueItem.Writer.TryBeginWrite(tmpSerializer.Length + FastBufferWriter.GetWriteSize<MessageHeader>());
var header = new MessageHeader var header = new MessageHeader
{ {
MessageSize = (ushort)tmpSerializer.Length, MessageSize = (ushort)tmpSerializer.Length,
@@ -363,11 +368,11 @@ namespace Unity.Netcode
writeQueueItem.BatchHeader.BatchSize++; writeQueueItem.BatchHeader.BatchSize++;
for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx) for (var hookIdx = 0; hookIdx < m_Hooks.Count; ++hookIdx)
{ {
m_Hooks[hookIdx].OnAfterSendMessage(clientId, typeof(TMessageType), delivery, tmpSerializer.Length + sizeof(MessageHeader)); m_Hooks[hookIdx].OnAfterSendMessage(clientId, typeof(TMessageType), delivery, tmpSerializer.Length + FastBufferWriter.GetWriteSize<MessageHeader>());
} }
} }
return tmpSerializer.Length; return tmpSerializer.Length + FastBufferWriter.GetWriteSize<MessageHeader>();
} }
} }

View File

@@ -8,17 +8,22 @@ using UnityEngine.SceneManagement;
namespace Unity.Netcode namespace Unity.Netcode
{ {
/// <summary> /// <summary>
/// Used for local notifications of various scene events. /// Used for local notifications of various scene events. The <see cref="NetworkSceneManager.OnSceneEvent"/> of
/// The <see cref="NetworkSceneManager.OnSceneEvent"/> of delegate type <see cref="NetworkSceneManager.SceneEventDelegate"/> uses this class to provide /// delegate type <see cref="NetworkSceneManager.SceneEventDelegate"/> uses this class to provide
/// scene event status/state. /// scene event status.<br/>
/// <em>Note: This is only when <see cref="NetworkConfig.EnableSceneManagement"/> is enabled.</em><br/>
/// See also: <br/>
/// <seealso cref="SceneEventType"/>
/// </summary> /// </summary>
public class SceneEvent public class SceneEvent
{ {
/// <summary> /// <summary>
/// The <see cref="UnityEngine.AsyncOperation"/> returned by <see cref="SceneManager"/> /// The <see cref="UnityEngine.AsyncOperation"/> returned by <see cref="SceneManager"/><BR/>
/// This is set for the following <see cref="Netcode.SceneEventType"/>s: /// This is set for the following <see cref="Netcode.SceneEventType"/>s:
/// <see cref="SceneEventType.Load"/> /// <list type="bullet">
/// <see cref="SceneEventType.Unload"/> /// <item><term><see cref="SceneEventType.Load"/></term></item>
/// <item><term><see cref="SceneEventType.Unload"/></term></item>
/// </list>
/// </summary> /// </summary>
public AsyncOperation AsyncOperation; public AsyncOperation AsyncOperation;
@@ -28,71 +33,92 @@ namespace Unity.Netcode
public SceneEventType SceneEventType; public SceneEventType SceneEventType;
/// <summary> /// <summary>
/// If applicable, this reflects the type of scene loading or unloading that is occurring. /// If applicable, this reflects the type of scene loading or unloading that is occurring.<BR/>
/// This is set for the following <see cref="Netcode.SceneEventType"/>s: /// This is set for the following <see cref="Netcode.SceneEventType"/>s:
/// <see cref="SceneEventType.Load"/> /// <list type="bullet">
/// <see cref="SceneEventType.Unload"/> /// <item><term><see cref="SceneEventType.Load"/></term></item>
/// <see cref="SceneEventType.LoadComplete"/> /// <item><term><see cref="SceneEventType.Unload"/></term></item>
/// <see cref="SceneEventType.UnloadComplete"/> /// <item><term><see cref="SceneEventType.LoadComplete"/></term></item>
/// <see cref="SceneEventType.LoadEventCompleted"/> /// <item><term><see cref="SceneEventType.UnloadComplete"/></term></item>
/// <see cref="SceneEventType.UnloadEventCompleted"/> /// <item><term><see cref="SceneEventType.LoadEventCompleted"/></term></item>
/// <item><term><see cref="SceneEventType.UnloadEventCompleted"/></term></item>
/// </list>
/// </summary> /// </summary>
public LoadSceneMode LoadSceneMode; public LoadSceneMode LoadSceneMode;
/// <summary> /// <summary>
/// This will be set to the scene name that the event pertains to. /// This will be set to the scene name that the event pertains to.<BR/>
/// This is set for the following <see cref="Netcode.SceneEventType"/>s: /// This is set for the following <see cref="Netcode.SceneEventType"/>s:
/// <see cref="SceneEventType.Load"/> /// <list type="bullet">
/// <see cref="SceneEventType.Unload"/> /// <item><term><see cref="SceneEventType.Load"/></term></item>
/// <see cref="SceneEventType.LoadComplete"/> /// <item><term><see cref="SceneEventType.Unload"/></term></item>
/// <see cref="SceneEventType.UnloadComplete"/> /// <item><term><see cref="SceneEventType.LoadComplete"/></term></item>
/// <see cref="SceneEventType.LoadEventCompleted"/> /// <item><term><see cref="SceneEventType.UnloadComplete"/></term></item>
/// <see cref="SceneEventType.UnloadEventCompleted"/> /// <item><term><see cref="SceneEventType.LoadEventCompleted"/></term></item>
/// <item><term><see cref="SceneEventType.UnloadEventCompleted"/></term></item>
/// </list>
/// </summary> /// </summary>
public string SceneName; public string SceneName;
/// <summary> /// <summary>
/// When a scene is loaded, the Scene structure is returned. /// When a scene is loaded, the Scene structure is returned.<BR/>
/// This is set for the following <see cref="Netcode.SceneEventType"/>s: /// This is set for the following <see cref="Netcode.SceneEventType"/>s:
/// <see cref="SceneEventType.LoadComplete"/> /// <list type="bullet">
/// <item><term><see cref="SceneEventType.LoadComplete"/></term></item>
/// </list>
/// </summary> /// </summary>
public Scene Scene; public Scene Scene;
/// <summary> /// <summary>
/// Events that always set the <see cref="ClientId"/> to the local client identifier, /// The client identifier can vary depending upon the following conditions: <br/>
/// are initiated (and processed locally) by the server-host, and sent to all clients /// <list type="number">
/// to be processed: /// <item><term><see cref="Netcode.SceneEventType"/>s that always set the <see cref="ClientId"/>
/// <see cref="SceneEventType.Load"/> /// to the local client identifier, are initiated (and processed locally) by the
/// <see cref="SceneEventType.Unload"/> /// server-host, and sent to all clients to be processed.<br/>
/// <see cref="SceneEventType.Synchronize"/> /// <list type="bullet">
/// <see cref="SceneEventType.ReSynchronize"/> /// <item><term><see cref="SceneEventType.Load"/></term></item>
/// /// <item><term><see cref="SceneEventType.Unload"/></term></item>
/// Events that always set the <see cref="ClientId"/> to the local client identifier, /// <item><term><see cref="SceneEventType.Synchronize"/></term></item>
/// <item><term><see cref="SceneEventType.ReSynchronize"/></term></item>
/// </list>
/// </term></item>
/// <item><term>Events that always set the <see cref="ClientId"/> to the local client identifier,
/// are initiated (and processed locally) by a client or server-host, and if initiated /// are initiated (and processed locally) by a client or server-host, and if initiated
/// by a client will always be sent to and processed on the server-host: /// by a client will always be sent to and processed on the server-host:
/// <see cref="SceneEventType.LoadComplete"/> /// <list type="bullet">
/// <see cref="SceneEventType.UnloadComplete"/> /// <item><term><see cref="SceneEventType.LoadComplete"/></term></item>
/// <see cref="SceneEventType.SynchronizeComplete"/> /// <item><term><see cref="SceneEventType.UnloadComplete"/></term></item>
/// /// <item><term><see cref="SceneEventType.SynchronizeComplete"/></term></item>
/// </list>
/// </term></item>
/// <item><term>
/// Events that always set the <see cref="ClientId"/> to the ServerId: /// Events that always set the <see cref="ClientId"/> to the ServerId:
/// <see cref="SceneEventType.LoadEventCompleted"/> /// <list type="bullet">
/// <see cref="SceneEventType.UnloadEventCompleted"/> /// <item><term><see cref="SceneEventType.LoadEventCompleted"/></term></item>
/// <item><term><see cref="SceneEventType.UnloadEventCompleted"/></term></item>
/// </list>
/// </term></item>
/// </list>
/// </summary> /// </summary>
public ulong ClientId; public ulong ClientId;
/// <summary> /// <summary>
/// List of clients that completed a loading or unloading event /// List of clients that completed a loading or unloading event.<br/>
/// This is set for the following <see cref="Netcode.SceneEventType"/>s: /// This is set for the following <see cref="Netcode.SceneEventType"/>s:
/// <see cref="SceneEventType.LoadEventCompleted"/> /// <list type="bullet">
/// <see cref="SceneEventType.UnloadEventCompleted"/> /// <item><term><see cref="SceneEventType.LoadEventCompleted"/></term></item>
/// <item><term><see cref="SceneEventType.UnloadEventCompleted"/></term></item>
/// </list>
/// </summary> /// </summary>
public List<ulong> ClientsThatCompleted; public List<ulong> ClientsThatCompleted;
/// <summary> /// <summary>
/// List of clients that timed out during a loading or unloading event /// List of clients that timed out during a loading or unloading event.<br/>
/// This is set for the following <see cref="Netcode.SceneEventType"/>s: /// This is set for the following <see cref="Netcode.SceneEventType"/>s:
/// <see cref="SceneEventType.LoadEventCompleted"/> /// <list type="bullet">
/// <see cref="SceneEventType.UnloadEventCompleted"/> /// <item><term><see cref="SceneEventType.LoadEventCompleted"/></term></item>
/// <item><term><see cref="SceneEventType.UnloadEventCompleted"/></term></item>
/// </list>
/// </summary> /// </summary>
public List<ulong> ClientsThatTimedOut; public List<ulong> ClientsThatTimedOut;
} }
@@ -122,34 +148,37 @@ namespace Unity.Netcode
#endif #endif
/// <summary> /// <summary>
/// The delegate callback definition for scene event notifications /// The delegate callback definition for scene event notifications.<br/>
/// For more details review over <see cref="SceneEvent"/> and <see cref="SceneEventData"/> /// See also: <br/>
/// <seealso cref="SceneEvent"/><br/>
/// <seealso cref="SceneEventData"/>
/// </summary> /// </summary>
/// <param name="sceneEvent"></param> /// <param name="sceneEvent"></param>
public delegate void SceneEventDelegate(SceneEvent sceneEvent); public delegate void SceneEventDelegate(SceneEvent sceneEvent);
/// <summary> /// <summary>
/// Event that will notify the local client or server of all scene events that take place /// Subscribe to this event to receive all <see cref="SceneEventType"/> notifications.<br/>
/// For more details review over <see cref="SceneEvent"/>, <see cref="SceneEventData"/>, and <see cref="SceneEventType"/> /// For more details review over <see cref="SceneEvent"/> and <see cref="SceneEventType"/>.<br/>
/// Subscribe to this event to receive all <see cref="SceneEventType"/> notifications /// <b>Alternate Single Event Type Notification Registration Options</b><br/>
///
/// Alternate Single Event Type Notification Registration Options
/// To receive only a specific event type notification or a limited set of notifications you can alternately subscribe to /// To receive only a specific event type notification or a limited set of notifications you can alternately subscribe to
/// each notification type individually via the following events: /// each notification type individually via the following events:<br/>
/// -- <see cref="OnLoad"/> Invoked only when a <see cref="SceneEventType.Load"/> event is being processed /// <list type="bullet">
/// -- <see cref="OnUnload"/> Invoked only when an <see cref="SceneEventType.Unload"/> event is being processed /// <item><term><see cref="OnLoad"/> Invoked only when a <see cref="SceneEventType.Load"/> event is being processed</term></item>
/// -- <see cref="OnSynchronize"/> Invoked only when a <see cref="SceneEventType.Synchronize"/> event is being processed /// <item><term><see cref="OnUnload"/> Invoked only when an <see cref="SceneEventType.Unload"/> event is being processed</term></item>
/// -- <see cref="OnLoadEventCompleted"/> Invoked only when a <see cref="SceneEventType.LoadEventCompleted"/> event is being processed /// <item><term><see cref="OnSynchronize"/> Invoked only when a <see cref="SceneEventType.Synchronize"/> event is being processed</term></item>
/// -- <see cref="OnUnloadEventCompleted"/> Invoked only when an <see cref="SceneEventType.UnloadEventCompleted"/> event is being processed /// <item><term><see cref="OnLoadEventCompleted"/> Invoked only when a <see cref="SceneEventType.LoadEventCompleted"/> event is being processed</term></item>
/// -- <see cref="OnLoadComplete"/> Invoked only when a <see cref="SceneEventType.LoadComplete"/> event is being processed /// <item><term><see cref="OnUnloadEventCompleted"/> Invoked only when an <see cref="SceneEventType.UnloadEventCompleted"/> event is being processed</term></item>
/// -- <see cref="OnUnloadComplete"/> Invoked only when an <see cref="SceneEventType.UnloadComplete"/> event is being processed /// <item><term><see cref="OnLoadComplete"/> Invoked only when a <see cref="SceneEventType.LoadComplete"/> event is being processed</term></item>
/// -- <see cref="OnSynchronizeComplete"/> Invoked only when a <see cref="SceneEventType.SynchronizeComplete"/> event is being processed /// <item><term><see cref="OnUnloadComplete"/> Invoked only when an <see cref="SceneEventType.UnloadComplete"/> event is being processed</term></item>
/// <item><term><see cref="OnSynchronizeComplete"/> Invoked only when a <see cref="SceneEventType.SynchronizeComplete"/> event is being processed</term></item>
/// </list>
/// </summary> /// </summary>
public event SceneEventDelegate OnSceneEvent; public event SceneEventDelegate OnSceneEvent;
/// <summary> /// <summary>
/// Delegate declaration for the OnLoad event /// Delegate declaration for the OnLoad event.<br/>
/// View <see cref="SceneEventType.Load"/> for more information /// See also: <br/>
/// <seealso cref="SceneEventType.Load"/>for more information
/// </summary> /// </summary>
/// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param> /// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param>
/// <param name="sceneName">name of the scene being processed</param> /// <param name="sceneName">name of the scene being processed</param>
@@ -158,8 +187,9 @@ namespace Unity.Netcode
public delegate void OnLoadDelegateHandler(ulong clientId, string sceneName, LoadSceneMode loadSceneMode, AsyncOperation asyncOperation); public delegate void OnLoadDelegateHandler(ulong clientId, string sceneName, LoadSceneMode loadSceneMode, AsyncOperation asyncOperation);
/// <summary> /// <summary>
/// Delegate declaration for the OnUnload event /// Delegate declaration for the OnUnload event.<br/>
/// View <see cref="SceneEventType.Unload"/> for more information /// See also: <br/>
/// <seealso cref="SceneEventType.Unload"/> for more information
/// </summary> /// </summary>
/// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param> /// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param>
/// <param name="sceneName">name of the scene being processed</param> /// <param name="sceneName">name of the scene being processed</param>
@@ -167,16 +197,18 @@ namespace Unity.Netcode
public delegate void OnUnloadDelegateHandler(ulong clientId, string sceneName, AsyncOperation asyncOperation); public delegate void OnUnloadDelegateHandler(ulong clientId, string sceneName, AsyncOperation asyncOperation);
/// <summary> /// <summary>
/// Delegate declaration for the OnSynchronize event /// Delegate declaration for the OnSynchronize event.<br/>
/// View <see cref="SceneEventType.Synchronize"/> for more information /// See also: <br/>
/// <seealso cref="SceneEventType.Synchronize"/> for more information
/// </summary> /// </summary>
/// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param> /// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param>
public delegate void OnSynchronizeDelegateHandler(ulong clientId); public delegate void OnSynchronizeDelegateHandler(ulong clientId);
/// <summary> /// <summary>
/// Delegate declaration for the OnLoadEventCompleted and OnUnloadEventCompleted events /// Delegate declaration for the OnLoadEventCompleted and OnUnloadEventCompleted events.<br/>
/// View <see cref="SceneEventType.LoadEventCompleted"/> for more information /// See also:<br/>
/// View <see cref="SceneEventType.UnloadEventCompleted"/> for more information /// <seealso cref="SceneEventType.LoadEventCompleted"/><br/>
/// <seealso cref="SceneEventType.UnloadEventCompleted"/>
/// </summary> /// </summary>
/// <param name="sceneName">scene pertaining to this event</param> /// <param name="sceneName">scene pertaining to this event</param>
/// <param name="loadSceneMode"><see cref="LoadSceneMode"/> of the associated event completed</param> /// <param name="loadSceneMode"><see cref="LoadSceneMode"/> of the associated event completed</param>
@@ -185,8 +217,9 @@ namespace Unity.Netcode
public delegate void OnEventCompletedDelegateHandler(string sceneName, LoadSceneMode loadSceneMode, List<ulong> clientsCompleted, List<ulong> clientsTimedOut); public delegate void OnEventCompletedDelegateHandler(string sceneName, LoadSceneMode loadSceneMode, List<ulong> clientsCompleted, List<ulong> clientsTimedOut);
/// <summary> /// <summary>
/// Delegate declaration for the OnLoadComplete event /// Delegate declaration for the OnLoadComplete event.<br/>
/// View <see cref="SceneEventType.LoadComplete"/> for more information /// See also:<br/>
/// <seealso cref="SceneEventType.LoadComplete"/> for more information
/// </summary> /// </summary>
/// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param> /// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param>
/// <param name="sceneName">the scene name pertaining to this event</param> /// <param name="sceneName">the scene name pertaining to this event</param>
@@ -194,38 +227,40 @@ namespace Unity.Netcode
public delegate void OnLoadCompleteDelegateHandler(ulong clientId, string sceneName, LoadSceneMode loadSceneMode); public delegate void OnLoadCompleteDelegateHandler(ulong clientId, string sceneName, LoadSceneMode loadSceneMode);
/// <summary> /// <summary>
/// Delegate declaration for the OnUnloadComplete event /// Delegate declaration for the OnUnloadComplete event.<br/>
/// View <see cref="SceneEventType.UnloadComplete"/> for more information /// See also:<br/>
/// <seealso cref="SceneEventType.UnloadComplete"/> for more information
/// </summary> /// </summary>
/// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param> /// <param name="clientId">the client that is processing this event (the server will receive all of these events for every client and itself)</param>
/// <param name="sceneName">the scene name pertaining to this event</param> /// <param name="sceneName">the scene name pertaining to this event</param>
public delegate void OnUnloadCompleteDelegateHandler(ulong clientId, string sceneName); public delegate void OnUnloadCompleteDelegateHandler(ulong clientId, string sceneName);
/// <summary> /// <summary>
/// Delegate declaration for the OnSynchronizeComplete event /// Delegate declaration for the OnSynchronizeComplete event.<br/>
/// View <see cref="SceneEventType.SynchronizeComplete"/> for more information /// See also:<br/>
/// <seealso cref="SceneEventType.SynchronizeComplete"/> for more information
/// </summary> /// </summary>
/// <param name="clientId">the client that completed this event</param> /// <param name="clientId">the client that completed this event</param>
public delegate void OnSynchronizeCompleteDelegateHandler(ulong clientId); public delegate void OnSynchronizeCompleteDelegateHandler(ulong clientId);
/// <summary> /// <summary>
/// Invoked when a <see cref="SceneEventType.Load"/> event is started by the server /// Invoked when a <see cref="SceneEventType.Load"/> event is started by the server.<br/>
/// The server and client(s) will receive this notification /// <em>Note: The server and connected client(s) will always receive this notification.</em>
/// </summary> /// </summary>
public event OnLoadDelegateHandler OnLoad; public event OnLoadDelegateHandler OnLoad;
/// <summary> /// <summary>
/// Invoked when a <see cref="SceneEventType.Unload"/> event is started by the server /// Invoked when a <see cref="SceneEventType.Unload"/> event is started by the server.<br/>
/// The server and client(s) will receive this notification /// <em>Note: The server and connected client(s) will always receive this notification.</em>
/// </summary> /// </summary>
public event OnUnloadDelegateHandler OnUnload; public event OnUnloadDelegateHandler OnUnload;
/// <summary> /// <summary>
/// Invoked when a <see cref="SceneEventType.Synchronize"/> event is started by the server /// Invoked when a <see cref="SceneEventType.Synchronize"/> event is started by the server
/// after a client is approved for connection in order to synchronize the client with the currently loaded /// after a client is approved for connection in order to synchronize the client with the currently loaded
/// scenes and NetworkObjects. This event signifies the beginning of the synchronization event. /// scenes and NetworkObjects. This event signifies the beginning of the synchronization event.<br/>
/// The server and client will receive this notification /// <em>Note: The server and connected client(s) will always receive this notification.
/// Note: this event is generated on a per newly connected and approved client basis /// This event is generated on a per newly connected and approved client basis.</em>
/// </summary> /// </summary>
public event OnSynchronizeDelegateHandler OnSynchronize; public event OnSynchronizeDelegateHandler OnSynchronize;
@@ -233,8 +268,8 @@ namespace Unity.Netcode
/// Invoked when a <see cref="SceneEventType.LoadEventCompleted"/> event is generated by the server. /// Invoked when a <see cref="SceneEventType.LoadEventCompleted"/> event is generated by the server.
/// This event signifies the end of an existing <see cref="SceneEventType.Load"/> event as it pertains /// This event signifies the end of an existing <see cref="SceneEventType.Load"/> event as it pertains
/// to all clients connected when the event was started. This event signifies that all clients (and server) have /// to all clients connected when the event was started. This event signifies that all clients (and server) have
/// finished the <see cref="SceneEventType.Load"/> event. /// finished the <see cref="SceneEventType.Load"/> event.<br/>
/// Note: this is useful to know when all clients have loaded the same scene (single or additive mode) /// <em>Note: this is useful to know when all clients have loaded the same scene (single or additive mode)</em>
/// </summary> /// </summary>
public event OnEventCompletedDelegateHandler OnLoadEventCompleted; public event OnEventCompletedDelegateHandler OnLoadEventCompleted;
@@ -242,32 +277,31 @@ namespace Unity.Netcode
/// Invoked when a <see cref="SceneEventType.UnloadEventCompleted"/> event is generated by the server. /// Invoked when a <see cref="SceneEventType.UnloadEventCompleted"/> event is generated by the server.
/// This event signifies the end of an existing <see cref="SceneEventType.Unload"/> event as it pertains /// This event signifies the end of an existing <see cref="SceneEventType.Unload"/> event as it pertains
/// to all clients connected when the event was started. This event signifies that all clients (and server) have /// to all clients connected when the event was started. This event signifies that all clients (and server) have
/// finished the <see cref="SceneEventType.Unload"/> event. /// finished the <see cref="SceneEventType.Unload"/> event.<br/>
/// Note: this is useful to know when all clients have unloaded a specific scene. The <see cref="LoadSceneMode"/> will /// <em>Note: this is useful to know when all clients have unloaded a specific scene. The <see cref="LoadSceneMode"/> will
/// always be <see cref="LoadSceneMode.Additive"/> for this event /// always be <see cref="LoadSceneMode.Additive"/> for this event.</em>
/// </summary> /// </summary>
public event OnEventCompletedDelegateHandler OnUnloadEventCompleted; public event OnEventCompletedDelegateHandler OnUnloadEventCompleted;
/// <summary> /// <summary>
/// Invoked when a <see cref="SceneEventType.LoadComplete"/> event is generated by a client or server. /// Invoked when a <see cref="SceneEventType.LoadComplete"/> event is generated by a client or server.<br/>
/// The server receives this message from all clients (including itself). /// <em>Note: The server receives this message from all clients (including itself).
/// Each client receives their own notification sent to the server. /// Each client receives their own notification sent to the server.</em>
/// </summary> /// </summary>
public event OnLoadCompleteDelegateHandler OnLoadComplete; public event OnLoadCompleteDelegateHandler OnLoadComplete;
/// <summary> /// <summary>
/// Invoked when a <see cref="SceneEventType.UnloadComplete"/> event is generated by a client or server. /// Invoked when a <see cref="SceneEventType.UnloadComplete"/> event is generated by a client or server.<br/>
/// The server receives this message from all clients (including itself). /// <em>Note: The server receives this message from all clients (including itself).
/// Each client receives their own notification sent to the server. /// Each client receives their own notification sent to the server.</em>
/// </summary> /// </summary>
public event OnUnloadCompleteDelegateHandler OnUnloadComplete; public event OnUnloadCompleteDelegateHandler OnUnloadComplete;
/// <summary> /// <summary>
/// Invoked when a <see cref="SceneEventType.SynchronizeComplete"/> event is generated by a client. /// Invoked when a <see cref="SceneEventType.SynchronizeComplete"/> event is generated by a client. <br/>
/// The server receives this message from the client, but will never generate this event for itself. /// <em> Note: The server receives this message from the client, but will never generate this event for itself.
/// Each client receives their own notification sent to the server. /// Each client receives their own notification sent to the server. This is useful to know that a client has
/// Note: This is useful to know that a client has completed the entire connection sequence, loaded all scenes, and /// completed the entire connection sequence, loaded all scenes, and synchronized all NetworkObjects.</em>
/// synchronized all NetworkObjects.
/// </summary> /// </summary>
public event OnSynchronizeCompleteDelegateHandler OnSynchronizeComplete; public event OnSynchronizeCompleteDelegateHandler OnSynchronizeComplete;
@@ -284,9 +318,9 @@ namespace Unity.Netcode
/// <summary> /// <summary>
/// Delegate handler defined by <see cref="VerifySceneBeforeLoadingDelegateHandler"/> that is invoked before the /// Delegate handler defined by <see cref="VerifySceneBeforeLoadingDelegateHandler"/> that is invoked before the
/// server or client loads a scene during an active netcode game session. /// server or client loads a scene during an active netcode game session.<br/>
/// Client Side: In order for clients to be notified of this condition you must assign the <see cref="VerifySceneBeforeLoading"/> delegate handler. /// <b>Client Side:</b> In order for clients to be notified of this condition you must assign the <see cref="VerifySceneBeforeLoading"/> delegate handler.<br/>
/// Server Side: <see cref="LoadScene(string, LoadSceneMode)"/> will return <see cref="SceneEventProgressStatus.SceneFailedVerification"/>. /// <b>Server Side:</b> <see cref="LoadScene(string, LoadSceneMode)"/> will return <see cref="SceneEventProgressStatus"/>.
/// </summary> /// </summary>
public VerifySceneBeforeLoadingDelegateHandler VerifySceneBeforeLoading; public VerifySceneBeforeLoadingDelegateHandler VerifySceneBeforeLoading;
@@ -353,11 +387,10 @@ namespace Unity.Netcode
internal Scene DontDestroyOnLoadScene; internal Scene DontDestroyOnLoadScene;
/// <summary> /// <summary>
/// LoadSceneMode.Single: All currently loaded scenes on the client will be unloaded and /// <b>LoadSceneMode.Single:</b> All currently loaded scenes on the client will be unloaded and
/// the server's currently active scene will be loaded in single mode on the client /// the server's currently active scene will be loaded in single mode on the client
/// unless it was already loaded. /// unless it was already loaded.<br/>
/// /// <b>LoadSceneMode.Additive:</b> All currently loaded scenes are left as they are and any newly loaded
/// LoadSceneMode.Additive: All currently loaded scenes are left as they are and any newly loaded
/// scenes will be loaded additively. Users need to determine which scenes are valid to load via the /// scenes will be loaded additively. Users need to determine which scenes are valid to load via the
/// <see cref="VerifySceneBeforeLoading"/> method. /// <see cref="VerifySceneBeforeLoading"/> method.
/// </summary> /// </summary>
@@ -506,12 +539,11 @@ namespace Unity.Netcode
} }
/// <summary> /// <summary>
/// This will change how clients are initially synchronized. /// This will change how clients are initially synchronized.<br/>
/// LoadSceneMode.Single: All currently loaded scenes on the client will be unloaded and /// <b>LoadSceneMode.Single:</b> All currently loaded scenes on the client will be unloaded and
/// the server's currently active scene will be loaded in single mode on the client /// the server's currently active scene will be loaded in single mode on the client
/// unless it was already loaded. /// unless it was already loaded. <br/>
/// /// <b>LoadSceneMode.Additive:</b> All currently loaded scenes are left as they are and any newly loaded
/// LoadSceneMode.Additive: All currently loaded scenes are left as they are and any newly loaded
/// scenes will be loaded additively. Users need to determine which scenes are valid to load via the /// scenes will be loaded additively. Users need to determine which scenes are valid to load via the
/// <see cref="VerifySceneBeforeLoading"/> method. /// <see cref="VerifySceneBeforeLoading"/> method.
/// </summary> /// </summary>
@@ -858,7 +890,7 @@ namespace Unity.Netcode
} }
/// <summary> /// <summary>
/// Server Side: /// <b>Server Side:</b>
/// Unloads an additively loaded scene. If you want to unload a <see cref="LoadSceneMode.Single"/> mode loaded scene load another <see cref="LoadSceneMode.Single"/> scene. /// Unloads an additively loaded scene. If you want to unload a <see cref="LoadSceneMode.Single"/> mode loaded scene load another <see cref="LoadSceneMode.Single"/> scene.
/// When applicable, the <see cref="AsyncOperation"/> is delivered within the <see cref="SceneEvent"/> via the <see cref="OnSceneEvent"/> /// When applicable, the <see cref="AsyncOperation"/> is delivered within the <see cref="SceneEvent"/> via the <see cref="OnSceneEvent"/>
/// </summary> /// </summary>
@@ -918,7 +950,7 @@ namespace Unity.Netcode
} }
/// <summary> /// <summary>
/// Client Side: /// <b>Client Side:</b>
/// Handles <see cref="SceneEventType.Unload"/> scene events. /// Handles <see cref="SceneEventType.Unload"/> scene events.
/// </summary> /// </summary>
private void OnClientUnloadScene(uint sceneEventId) private void OnClientUnloadScene(uint sceneEventId)
@@ -1056,7 +1088,7 @@ namespace Unity.Netcode
} }
/// <summary> /// <summary>
/// Server side: /// <b>Server side:</b>
/// Loads the scene name in either additive or single loading mode. /// Loads the scene name in either additive or single loading mode.
/// When applicable, the <see cref="AsyncOperation"/> is delivered within the <see cref="SceneEvent"/> via <see cref="OnSceneEvent"/> /// When applicable, the <see cref="AsyncOperation"/> is delivered within the <see cref="SceneEvent"/> via <see cref="OnSceneEvent"/>
/// </summary> /// </summary>

View File

@@ -8,84 +8,86 @@ using UnityEngine.SceneManagement;
namespace Unity.Netcode namespace Unity.Netcode
{ {
/// <summary> /// <summary>
/// The different types of scene events communicated between a server and client. /// The different types of scene events communicated between a server and client. <br/>
/// Used by <see cref="NetworkSceneManager"/> for <see cref="SceneEventMessage"/> messages /// Used by <see cref="NetworkSceneManager"/> for <see cref="SceneEventMessage"/> messages.<br/>
/// Note: This is only when <see cref="NetworkConfig.EnableSceneManagement"/> is enabled /// <em>Note: This is only when <see cref="NetworkConfig.EnableSceneManagement"/> is enabled.</em><br/>
/// See also: <see cref="SceneEvent"/> /// See also: <br/>
/// <seealso cref="SceneEvent"/>
/// </summary> /// </summary>
public enum SceneEventType : byte public enum SceneEventType : byte
{ {
/// <summary> /// <summary>
/// Load a scene /// Load a scene<br/>
/// Invocation: Server Side /// <b>Invocation:</b> Server Side<br/>
/// Message Flow: Server to client /// <b>Message Flow:</b> Server to client<br/>
/// Event Notification: Both server and client are notified a load scene event started /// <b>Event Notification:</b> Both server and client are notified a load scene event started
/// </summary> /// </summary>
Load, Load,
/// <summary> /// <summary>
/// Unload a scene /// Unload a scene<br/>
/// Invocation: Server Side /// <b>Invocation:</b> Server Side<br/>
/// Message Flow: Server to client /// <b>Message Flow:</b> Server to client<br/>
/// Event Notification: Both server and client are notified an unload scene event started /// <b>Event Notification:</b> Both server and client are notified an unload scene event started.
/// </summary> /// </summary>
Unload, Unload,
/// <summary> /// <summary>
/// Synchronize current game session state for approved clients /// Synchronizes current game session state for newly approved clients<br/>
/// Invocation: Server Side /// <b>Invocation:</b> Server Side<br/>
/// Message Flow: Server to client /// <b>Message Flow:</b> Server to client<br/>
/// Event Notification: Server and Client receives a local notification (server receives the ClientId being synchronized) /// <b>Event Notification:</b> Server and Client receives a local notification (<em>server receives the ClientId being synchronized</em>).
/// </summary> /// </summary>
Synchronize, Synchronize,
/// <summary> /// <summary>
/// Game session re-synchronization of NetworkObjects that were destroyed during a <see cref="Synchronize"/> event /// Game session re-synchronization of NetworkObjects that were destroyed during a <see cref="Synchronize"/> event<br/>
/// Invocation: Server Side /// <b>Invocation:</b> Server Side<br/>
/// Message Flow: Server to client /// <b>Message Flow:</b> Server to client<br/>
/// Event Notification: Both server and client receive a local notification /// <b>Event Notification:</b> Both server and client receive a local notification<br/>
/// Note: This will be removed once snapshot and buffered messages are finalized as it will no longer be needed at that point /// <em>Note: This will be removed once snapshot and buffered messages are finalized as it will no longer be needed at that point.</em>
/// </summary> /// </summary>
ReSynchronize, ReSynchronize,
/// <summary> /// <summary>
/// All clients have finished loading a scene /// All clients have finished loading a scene<br/>
/// Invocation: Server Side /// <b>Invocation:</b> Server Side<br/>
/// Message Flow: Server to Client /// <b>Message Flow:</b> Server to Client<br/>
/// Event Notification: Both server and client receive a local notification containing the clients that finished /// <b>Event Notification:</b> Both server and client receive a local notification containing the clients that finished
/// as well as the clients that timed out (if any). /// as well as the clients that timed out(<em>if any</em>).
/// </summary> /// </summary>
LoadEventCompleted, LoadEventCompleted,
/// <summary> /// <summary>
/// All clients have unloaded a scene /// All clients have unloaded a scene<br/>
/// Invocation: Server Side /// <b>Invocation:</b> Server Side<br/>
/// Message Flow: Server to Client /// <b>Message Flow:</b> Server to Client<br/>
/// Event Notification: Both server and client receive a local notification containing the clients that finished /// <b>Event Notification:</b> Both server and client receive a local notification containing the clients that finished
/// as well as the clients that timed out (if any). /// as well as the clients that timed out(<em>if any</em>).
/// </summary> /// </summary>
UnloadEventCompleted, UnloadEventCompleted,
/// <summary> /// <summary>
/// A client has finished loading a scene /// A client has finished loading a scene<br/>
/// Invocation: Client Side /// <b>Invocation:</b> Client Side<br/>
/// Message Flow: Client to Server /// <b>Message Flow:</b> Client to Server<br/>
/// Event Notification: Both server and client receive a local notification /// <b>Event Notification:</b> Both server and client receive a local notification.
/// </summary> /// </summary>
LoadComplete, LoadComplete,
/// <summary> /// <summary>
/// A client has finished unloading a scene /// A client has finished unloading a scene<br/>
/// Invocation: Client Side /// <b>Invocation:</b> Client Side<br/>
/// Message Flow: Client to Server /// <b>Message Flow:</b> Client to Server<br/>
/// Event Notification: Both server and client receive a local notification /// <b>Event Notification:</b> Both server and client receive a local notification.
/// </summary> /// </summary>
UnloadComplete, UnloadComplete,
/// <summary> /// <summary>
/// A client has finished synchronizing from a <see cref="Synchronize"/> event /// A client has finished synchronizing from a <see cref="Synchronize"/> event<br/>
/// Invocation: Client Side /// <b>Invocation:</b> Client Side<br/>
/// Message Flow: Client to Server /// <b>Message Flow:</b> Client to Server<br/>
/// Event Notification: Both server and client receive a local notification /// <b>Event Notification:</b> Both server and client receive a local notification.
/// </summary> /// </summary>
SynchronizeComplete, SynchronizeComplete,
} }
/// <summary> /// <summary>
/// Used by <see cref="NetworkSceneManager"/> for <see cref="SceneEventMessage"/> messages /// Used by <see cref="NetworkSceneManager"/> for <see cref="SceneEventMessage"/> messages
/// Note: This is only when <see cref="NetworkConfig.EnableSceneManagement"/> is enabled /// <em>Note: This is only when <see cref="NetworkConfig.EnableSceneManagement"/> is enabled.</em><br/>
/// See also: <seealso cref="SceneEvent"/>
/// </summary> /// </summary>
internal class SceneEventData : IDisposable internal class SceneEventData : IDisposable
{ {

View File

@@ -9,10 +9,10 @@ namespace Unity.Netcode
{ {
/// <summary> /// <summary>
/// Used by <see cref="NetworkSceneManager"/> to determine if a server invoked scene event has started. /// Used by <see cref="NetworkSceneManager"/> to determine if a server invoked scene event has started.
/// The returned status is stored in the <see cref="SceneEventProgress.Status"/> property. /// The returned status is stored in the <see cref="SceneEventProgress.Status"/> property.<br/>
/// Note: This was formally known as SwitchSceneProgress which contained the <see cref="AsyncOperation"/>. /// <em>Note: This was formally known as SwitchSceneProgress which contained the <see cref="AsyncOperation"/>.
/// All <see cref="AsyncOperation"/>s are now delivered by the <see cref="NetworkSceneManager.OnSceneEvent"/> event handler /// All <see cref="AsyncOperation"/>s are now delivered by the <see cref="NetworkSceneManager.OnSceneEvent"/> event handler
/// via the <see cref="SceneEvent"/> parameter. /// via the <see cref="SceneEvent"/> parameter.</em>
/// </summary> /// </summary>
public enum SceneEventProgressStatus public enum SceneEventProgressStatus
{ {
@@ -21,31 +21,30 @@ namespace Unity.Netcode
/// </summary> /// </summary>
None, None,
/// <summary> /// <summary>
/// The scene event was successfully started /// The scene event was successfully started.
/// </summary> /// </summary>
Started, Started,
/// <summary> /// <summary>
/// Returned if you try to unload a scene that was not yet loaded /// Returned if you try to unload a scene that was not yet loaded.
/// </summary> /// </summary>
SceneNotLoaded, SceneNotLoaded,
/// <summary> /// <summary>
/// Returned if you try to start a new scene event before a previous one is finished /// Returned if you try to start a new scene event before a previous one is finished.
/// </summary> /// </summary>
SceneEventInProgress, SceneEventInProgress,
/// <summary> /// <summary>
/// Returned if the scene name used with <see cref="NetworkSceneManager.LoadScene(string, LoadSceneMode)"/> /// Returned if the scene name used with <see cref="NetworkSceneManager.LoadScene(string, LoadSceneMode)"/>
/// or <see cref="NetworkSceneManager.UnloadScene(Scene)"/>is invalid /// or <see cref="NetworkSceneManager.UnloadScene(Scene)"/>is invalid.
/// </summary> /// </summary>
InvalidSceneName, InvalidSceneName,
/// <summary> /// <summary>
/// Server side: Returned if the <see cref="NetworkSceneManager.VerifySceneBeforeLoading"/> delegate handler returns false /// Server side: Returned if the <see cref="NetworkSceneManager.VerifySceneBeforeLoading"/> delegate handler returns false
/// (i.e. scene is considered not valid/safe to load) /// (<em>i.e. scene is considered not valid/safe to load</em>).
/// </summary> /// </summary>
SceneFailedVerification, SceneFailedVerification,
/// <summary> /// <summary>
/// This is used for internal error notifications. /// This is used for internal error notifications.<br/>
/// If you receive this event then it is most likely due to a bug. /// If you receive this event then it is most likely due to a bug (<em>please open a GitHub issue with steps to replicate</em>).<br/>
/// If you receive this event repeatedly, then please open a GitHub issue with steps to replicate
/// </summary> /// </summary>
InternalNetcodeError, InternalNetcodeError,
} }

View File

@@ -24,6 +24,8 @@ namespace Unity.Netcode
internal readonly unsafe WriterHandle* Handle; internal readonly unsafe WriterHandle* Handle;
private static byte[] s_ByteArrayCache = new byte[65535];
/// <summary> /// <summary>
/// The current write position /// The current write position
/// </summary> /// </summary>
@@ -78,6 +80,10 @@ namespace Unity.Netcode
/// <param name="maxSize">Maximum size the buffer can grow to. If less than size, buffer cannot grow.</param> /// <param name="maxSize">Maximum size the buffer can grow to. If less than size, buffer cannot grow.</param>
public unsafe FastBufferWriter(int size, Allocator allocator, int maxSize = -1) public unsafe FastBufferWriter(int size, Allocator allocator, int maxSize = -1)
{ {
// Allocating both the Handle struct and the buffer in a single allocation - sizeof(WriterHandle) + size
// The buffer for the initial allocation is the next block of memory after the handle itself.
// If the buffer grows, a new buffer will be allocated and the handle pointer pointed at the new location...
// The original buffer won't be deallocated until the writer is destroyed since it's part of the handle allocation.
Handle = (WriterHandle*)UnsafeUtility.Malloc(sizeof(WriterHandle) + size, UnsafeUtility.AlignOf<WriterHandle>(), allocator); Handle = (WriterHandle*)UnsafeUtility.Malloc(sizeof(WriterHandle) + size, UnsafeUtility.AlignOf<WriterHandle>(), allocator);
#if DEVELOPMENT_BUILD || UNITY_EDITOR #if DEVELOPMENT_BUILD || UNITY_EDITOR
UnsafeUtility.MemSet(Handle, 0, sizeof(WriterHandle) + size); UnsafeUtility.MemSet(Handle, 0, sizeof(WriterHandle) + size);
@@ -349,6 +355,29 @@ namespace Unity.Netcode
return ret; return ret;
} }
/// <summary>
/// Uses a static cached array to create an array segment with no allocations.
/// This array can only be used until the next time ToTempByteArray() is called on ANY FastBufferWriter,
/// as the cached buffer is shared by all of them and will be overwritten.
/// As such, this should be used with care.
/// </summary>
/// <returns></returns>
internal unsafe ArraySegment<byte> ToTempByteArray()
{
var length = Length;
if (length > s_ByteArrayCache.Length)
{
return new ArraySegment<byte>(ToArray(), 0, length);
}
fixed (byte* b = s_ByteArrayCache)
{
UnsafeUtility.MemCpy(b, Handle->BufferPointer, length);
}
return new ArraySegment<byte>(s_ByteArrayCache, 0, length);
}
/// <summary> /// <summary>
/// Gets a direct pointer to the underlying buffer /// Gets a direct pointer to the underlying buffer
/// </summary> /// </summary>

View File

@@ -14,9 +14,9 @@ namespace Unity.Netcode.RuntimeTests.Metrics
{ {
public class MessagingMetricsTests : DualClientMetricTestBase public class MessagingMetricsTests : DualClientMetricTestBase
{ {
const uint MessageNameHashSize = 8; private const uint k_MessageNameHashSize = 8;
private static readonly int k_NamedMessageOverhead = (int)k_MessageNameHashSize + FastBufferWriter.GetWriteSize<MessageHeader>();
const uint MessageOverhead = MessageNameHashSize; private static readonly int k_UnnamedMessageOverhead = FastBufferWriter.GetWriteSize<MessageHeader>();
protected override int NbClients => 2; protected override int NbClients => 2;
@@ -111,7 +111,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
var namedMessageSent = namedMessageSentMetricValues.First(); var namedMessageSent = namedMessageSentMetricValues.First();
Assert.AreEqual(messageName.ToString(), namedMessageSent.Name); Assert.AreEqual(messageName.ToString(), namedMessageSent.Name);
Assert.AreEqual(FirstClient.LocalClientId, namedMessageSent.Connection.Id); Assert.AreEqual(FirstClient.LocalClientId, namedMessageSent.Connection.Id);
Assert.AreEqual(FastBufferWriter.GetWriteSize(messageName) + MessageOverhead, namedMessageSent.BytesCount); Assert.AreEqual(FastBufferWriter.GetWriteSize(messageName) + k_NamedMessageOverhead, namedMessageSent.BytesCount);
} }
[UnityTest] [UnityTest]
@@ -132,7 +132,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
var namedMessageSentMetricValues = waitForMetricValues.AssertMetricValuesHaveBeenFound(); var namedMessageSentMetricValues = waitForMetricValues.AssertMetricValuesHaveBeenFound();
Assert.AreEqual(2, namedMessageSentMetricValues.Count); Assert.AreEqual(2, namedMessageSentMetricValues.Count);
Assert.That(namedMessageSentMetricValues.Select(x => x.Name), Has.All.EqualTo(messageName.ToString())); Assert.That(namedMessageSentMetricValues.Select(x => x.Name), Has.All.EqualTo(messageName.ToString()));
Assert.That(namedMessageSentMetricValues.Select(x => x.BytesCount), Has.All.EqualTo(FastBufferWriter.GetWriteSize(messageName) + MessageOverhead)); Assert.That(namedMessageSentMetricValues.Select(x => x.BytesCount), Has.All.EqualTo(FastBufferWriter.GetWriteSize(messageName) + k_NamedMessageOverhead));
} }
[UnityTest] [UnityTest]
@@ -181,7 +181,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
var namedMessageReceived = namedMessageReceivedValues.First(); var namedMessageReceived = namedMessageReceivedValues.First();
Assert.AreEqual(messageName.ToString(), namedMessageReceived.Name); Assert.AreEqual(messageName.ToString(), namedMessageReceived.Name);
Assert.AreEqual(Server.LocalClientId, namedMessageReceived.Connection.Id); Assert.AreEqual(Server.LocalClientId, namedMessageReceived.Connection.Id);
Assert.AreEqual(FastBufferWriter.GetWriteSize(messageName) + MessageOverhead, namedMessageReceived.BytesCount); Assert.AreEqual(FastBufferWriter.GetWriteSize(messageName) + k_NamedMessageOverhead, namedMessageReceived.BytesCount);
} }
[UnityTest] [UnityTest]
@@ -205,7 +205,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
var unnamedMessageSent = unnamedMessageSentMetricValues.First(); var unnamedMessageSent = unnamedMessageSentMetricValues.First();
Assert.AreEqual(FirstClient.LocalClientId, unnamedMessageSent.Connection.Id); Assert.AreEqual(FirstClient.LocalClientId, unnamedMessageSent.Connection.Id);
Assert.AreEqual(FastBufferWriter.GetWriteSize(message), unnamedMessageSent.BytesCount); Assert.AreEqual(FastBufferWriter.GetWriteSize(message) + k_UnnamedMessageOverhead, unnamedMessageSent.BytesCount);
} }
[UnityTest] [UnityTest]
@@ -225,7 +225,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
var unnamedMessageSentMetricValues = waitForMetricValues.AssertMetricValuesHaveBeenFound(); var unnamedMessageSentMetricValues = waitForMetricValues.AssertMetricValuesHaveBeenFound();
Assert.AreEqual(2, unnamedMessageSentMetricValues.Count); Assert.AreEqual(2, unnamedMessageSentMetricValues.Count);
Assert.That(unnamedMessageSentMetricValues.Select(x => x.BytesCount), Has.All.EqualTo(FastBufferWriter.GetWriteSize(message))); Assert.That(unnamedMessageSentMetricValues.Select(x => x.BytesCount), Has.All.EqualTo(FastBufferWriter.GetWriteSize(message) + k_UnnamedMessageOverhead));
var clientIds = unnamedMessageSentMetricValues.Select(x => x.Connection.Id).ToList(); var clientIds = unnamedMessageSentMetricValues.Select(x => x.Connection.Id).ToList();
Assert.Contains(FirstClient.LocalClientId, clientIds); Assert.Contains(FirstClient.LocalClientId, clientIds);
@@ -268,7 +268,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
var unnamedMessageReceived = unnamedMessageReceivedValues.First(); var unnamedMessageReceived = unnamedMessageReceivedValues.First();
Assert.AreEqual(Server.LocalClientId, unnamedMessageReceived.Connection.Id); Assert.AreEqual(Server.LocalClientId, unnamedMessageReceived.Connection.Id);
Assert.AreEqual(FastBufferWriter.GetWriteSize(message), unnamedMessageReceived.BytesCount); Assert.AreEqual(FastBufferWriter.GetWriteSize(message) + k_UnnamedMessageOverhead, unnamedMessageReceived.BytesCount);
} }
} }
} }

View File

@@ -58,7 +58,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
var ownershipChangeSent = metricValues.First(); var ownershipChangeSent = metricValues.First();
Assert.AreEqual(networkObject.NetworkObjectId, ownershipChangeSent.NetworkId.NetworkId); Assert.AreEqual(networkObject.NetworkObjectId, ownershipChangeSent.NetworkId.NetworkId);
Assert.AreEqual(Server.LocalClientId, ownershipChangeSent.Connection.Id); Assert.AreEqual(Server.LocalClientId, ownershipChangeSent.Connection.Id);
Assert.AreEqual(FastBufferWriter.GetWriteSize<ChangeOwnershipMessage>(), ownershipChangeSent.BytesCount); Assert.AreEqual(FastBufferWriter.GetWriteSize<ChangeOwnershipMessage>() + FastBufferWriter.GetWriteSize<MessageHeader>(), ownershipChangeSent.BytesCount);
} }
[UnityTest] [UnityTest]

View File

@@ -11,6 +11,9 @@ namespace Unity.Netcode.RuntimeTests.Metrics
{ {
internal class ServerLogsMetricTests : SingleClientMetricTestBase internal class ServerLogsMetricTests : SingleClientMetricTestBase
{ {
private static readonly int k_ServerLogSentMessageOverhead = 2 + FastBufferWriter.GetWriteSize<MessageHeader>();
private static readonly int k_ServerLogReceivedMessageOverhead = 2;
[UnityTest] [UnityTest]
public IEnumerator TrackServerLogSentMetric() public IEnumerator TrackServerLogSentMetric()
{ {
@@ -27,7 +30,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
var sentMetric = sentMetrics.First(); var sentMetric = sentMetrics.First();
Assert.AreEqual(Server.LocalClientId, sentMetric.Connection.Id); Assert.AreEqual(Server.LocalClientId, sentMetric.Connection.Id);
Assert.AreEqual((uint)NetworkLog.LogType.Warning, (uint)sentMetric.LogLevel); Assert.AreEqual((uint)NetworkLog.LogType.Warning, (uint)sentMetric.LogLevel);
Assert.AreEqual(message.Length + 2, sentMetric.BytesCount); Assert.AreEqual(message.Length + k_ServerLogSentMessageOverhead, sentMetric.BytesCount);
} }
[UnityTest] [UnityTest]
@@ -46,7 +49,7 @@ namespace Unity.Netcode.RuntimeTests.Metrics
var receivedMetric = receivedMetrics.First(); var receivedMetric = receivedMetrics.First();
Assert.AreEqual(Client.LocalClientId, receivedMetric.Connection.Id); Assert.AreEqual(Client.LocalClientId, receivedMetric.Connection.Id);
Assert.AreEqual((uint)NetworkLog.LogType.Warning, (uint)receivedMetric.LogLevel); Assert.AreEqual((uint)NetworkLog.LogType.Warning, (uint)receivedMetric.LogLevel);
Assert.AreEqual(message.Length + 2, receivedMetric.BytesCount); Assert.AreEqual(message.Length + k_ServerLogReceivedMessageOverhead, receivedMetric.BytesCount);
} }
} }
} }

View File

@@ -2,7 +2,7 @@
"name": "com.unity.netcode.gameobjects", "name": "com.unity.netcode.gameobjects",
"displayName": "Netcode for GameObjects", "displayName": "Netcode for GameObjects",
"description": "Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.", "description": "Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.",
"version": "1.0.0-pre.2", "version": "1.0.0-pre.3",
"unity": "2020.3", "unity": "2020.3",
"dependencies": { "dependencies": {
"com.unity.modules.ai": "1.0.0", "com.unity.modules.ai": "1.0.0",
@@ -11,12 +11,12 @@
"com.unity.collections": "1.0.0-pre.5" "com.unity.collections": "1.0.0-pre.5"
}, },
"upmCi": { "upmCi": {
"footprint": "f3acafb35c17cf3cb48042bf9655c4ada00c34ae" "footprint": "883b3567bbb5155b7d06ef3c2cac755efa58a235"
}, },
"repository": { "repository": {
"url": "https://github.com/Unity-Technologies/com.unity.netcode.gameobjects.git", "url": "https://github.com/Unity-Technologies/com.unity.netcode.gameobjects.git",
"type": "git", "type": "git",
"revision": "bcef5b992c5414707ff48c95a48a113fd0e09ad3" "revision": "3e4df72dadeea8bd622da2824e30541910c79d3d"
}, },
"samples": [ "samples": [
{ {