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). ## [2.0.0-pre.3] - 2024-07-23 ### Added - Added: `UnityTransport.GetNetworkDriver` and `UnityTransport.GetLocalEndpoint` methods to expose the driver and local endpoint being used. (#2978) ### Fixed - Fixed issue where deferred despawn was causing GC allocations when converting an `IEnumerable` to a list. (#2983) - Fixed issue where the realtime network stats monitor was not able to display RPC traffic in release builds due to those stats being only available in development builds or the editor. (#2979) - Fixed issue where `NetworkManager.ScenesLoaded` was not being updated if `PostSynchronizationSceneUnloading` was set and any loaded scenes not used during synchronization were unloaded. (#2971) - Fixed issue where `Rigidbody2d` under Unity 6000.0.11f1 has breaking changes where `velocity` is now `linearVelocity` and `isKinematic` is replaced by `bodyType`. (#2971) - Fixed issue where `NetworkSpawnManager.InstantiateAndSpawn` and `NetworkObject.InstantiateAndSpawn` were not honoring the ownerClientId parameter when using a client-server network topology. (#2968) - Fixed issue where internal delta serialization could not have a byte serializer defined when serializing deltas for other types. Added `[GenerateSerializationForType(typeof(byte))]` to both the `NetworkVariable` and `AnticipatedNetworkVariable` classes to assure a byte serializer is defined.(#2962) - Fixed issue when scene management was disabled and the session owner would still try to synchronize a late joining client. (#2962) - Fixed issue when using a distributed authority network topology where it would allow a session owner to spawn a `NetworkObject` prior to being approved. Now, an error message is logged and the `NetworkObject` will not be spawned prior to the client being approved. (#2962) - Fixed issue where attempting to spawn during `NetworkBehaviour.OnInSceneObjectsSpawned` and `NetworkBehaviour.OnNetworkSessionSynchronized` notifications would throw a collection modified exception. (#2962) ### Changed - Changed logic where clients can now set the `NetworkSceneManager` client synchronization mode when using a distributed authority network topology. (#2985)
108 lines
6.2 KiB
C#
108 lines
6.2 KiB
C#
using System;
|
|
using Unity.Collections;
|
|
|
|
namespace Unity.Netcode
|
|
{
|
|
/// <summary>
|
|
/// This class is instantiated for types that we can't determine ahead of time are serializable - types
|
|
/// that don't meet any of the constraints for methods that are available on FastBufferReader and
|
|
/// FastBufferWriter. These types may or may not be serializable through extension methods. To ensure
|
|
/// the user has time to pass in the delegates to UserNetworkVariableSerialization, the existence
|
|
/// of user serialization isn't checked until it's used, so if no serialization is provided, this
|
|
/// will throw an exception when an object containing the relevant NetworkVariable is spawned.
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
internal class FallbackSerializer<T> : INetworkVariableSerializer<T>
|
|
{
|
|
public NetworkVariableType Type => NetworkVariableType.Unknown;
|
|
public bool IsDistributedAuthorityOptimized => true;
|
|
|
|
private void ThrowArgumentError()
|
|
{
|
|
throw new ArgumentException($"Serialization has not been generated for type {typeof(T).FullName}. This can be addressed by adding a [{nameof(GenerateSerializationForGenericParameterAttribute)}] to your generic class that serializes this value (if you are using one), adding [{nameof(GenerateSerializationForTypeAttribute)}(typeof({typeof(T).FullName})] to the class or method that is attempting to serialize it, or creating a field on a {nameof(NetworkBehaviour)} of type {nameof(NetworkVariable<T>)}. If this error continues to appear after doing one of those things and this is a type you can change, then either implement {nameof(INetworkSerializable)} or mark it as serializable by memcpy by adding {nameof(INetworkSerializeByMemcpy)} to its interface list to enable automatic serialization generation. If not, assign serialization code to {nameof(UserNetworkVariableSerialization<T>)}.{nameof(UserNetworkVariableSerialization<T>.WriteValue)}, {nameof(UserNetworkVariableSerialization<T>)}.{nameof(UserNetworkVariableSerialization<T>.ReadValue)}, and {nameof(UserNetworkVariableSerialization<T>)}.{nameof(UserNetworkVariableSerialization<T>.DuplicateValue)}, or if it's serializable by memcpy (contains no pointers), wrap it in {typeof(ForceNetworkSerializeByMemcpy<>).Name}.");
|
|
}
|
|
|
|
public void Write(FastBufferWriter writer, ref T value)
|
|
{
|
|
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
|
{
|
|
ThrowArgumentError();
|
|
}
|
|
UserNetworkVariableSerialization<T>.WriteValue(writer, value);
|
|
}
|
|
public void Read(FastBufferReader reader, ref T value)
|
|
{
|
|
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
|
{
|
|
ThrowArgumentError();
|
|
}
|
|
UserNetworkVariableSerialization<T>.ReadValue(reader, out value);
|
|
}
|
|
|
|
public void WriteDelta(FastBufferWriter writer, ref T value, ref T previousValue)
|
|
{
|
|
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
|
{
|
|
ThrowArgumentError();
|
|
}
|
|
|
|
if (UserNetworkVariableSerialization<T>.WriteDelta == null || UserNetworkVariableSerialization<T>.ReadDelta == null)
|
|
{
|
|
UserNetworkVariableSerialization<T>.WriteValue(writer, value);
|
|
return;
|
|
}
|
|
UserNetworkVariableSerialization<T>.WriteDelta(writer, value, previousValue);
|
|
}
|
|
|
|
public void ReadDelta(FastBufferReader reader, ref T value)
|
|
{
|
|
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
|
{
|
|
ThrowArgumentError();
|
|
}
|
|
|
|
if (UserNetworkVariableSerialization<T>.WriteDelta == null || UserNetworkVariableSerialization<T>.ReadDelta == null)
|
|
{
|
|
UserNetworkVariableSerialization<T>.ReadValue(reader, out value);
|
|
return;
|
|
}
|
|
UserNetworkVariableSerialization<T>.ReadDelta(reader, ref value);
|
|
}
|
|
|
|
void INetworkVariableSerializer<T>.ReadWithAllocator(FastBufferReader reader, out T value, Allocator allocator)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void Duplicate(in T value, ref T duplicatedValue)
|
|
{
|
|
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
|
{
|
|
ThrowArgumentError();
|
|
}
|
|
UserNetworkVariableSerialization<T>.DuplicateValue(value, ref duplicatedValue);
|
|
}
|
|
|
|
public void WriteDistributedAuthority(FastBufferWriter writer, ref T value) => ThrowArgumentError();
|
|
public void ReadDistributedAuthority(FastBufferReader reader, ref T value) => ThrowArgumentError();
|
|
public void WriteDeltaDistributedAuthority(FastBufferWriter writer, ref T value, ref T previousValue) => ThrowArgumentError();
|
|
public void ReadDeltaDistributedAuthority(FastBufferReader reader, ref T value) => ThrowArgumentError();
|
|
}
|
|
|
|
// RuntimeAccessModifiersILPP will make this `public`
|
|
// This is just pass-through to NetworkVariableSerialization<T> but is here because I could not get ILPP
|
|
// to generate code that would successfully call Type<T>.Method(T), but it has no problem calling Type.Method<T>(T)
|
|
internal class RpcFallbackSerialization
|
|
{
|
|
public static void Write<T>(FastBufferWriter writer, ref T value)
|
|
{
|
|
NetworkVariableSerialization<T>.Write(writer, ref value);
|
|
}
|
|
|
|
public static void Read<T>(FastBufferReader reader, ref T value)
|
|
{
|
|
NetworkVariableSerialization<T>.Read(reader, ref value);
|
|
}
|
|
}
|
|
}
|