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.1] - 2024-06-17 ### Added - Added event `NetworkManager.OnSessionOwnerPromoted` that is invoked when a new session owner promotion occurs. (#2948) - Added `NetworkRigidBodyBase.GetLinearVelocity` and `NetworkRigidBodyBase.SetLinearVelocity` convenience/helper methods. (#2948) - Added `NetworkRigidBodyBase.GetAngularVelocity` and `NetworkRigidBodyBase.SetAngularVelocity` convenience/helper methods. (#2948) ### Fixed - Fixed issue when `NetworkTransform` half float precision is enabled and ownership changes the current base position was not being synchronized. (#2948) - Fixed issue where `OnClientConnected` not being invoked on the session owner when connecting to a new distributed authority session. (#2948) - Fixed issue where Rigidbody micro-motion (i.e. relatively small velocities) would result in non-authority instances slightly stuttering as the body would come to a rest (i.e. no motion). Now, the threshold value can increase at higher velocities and can decrease slightly below the provided threshold to account for this. (#2948) ### Changed - Changed the client's owned objects is now returned (`NetworkClient` and `NetworkSpawnManager`) as an array as opposed to a list for performance purposes. (#2948) - Changed `NetworkTransfrom.TryCommitTransformToServer` to be internal as it will be removed by the final 2.0.0 release. (#2948) - Changed `NetworkTransformEditor.OnEnable` to a virtual method to be able to customize a `NetworkTransform` derived class by creating a derived editor control from `NetworkTransformEditor`. (#2948)
116 lines
3.8 KiB
C#
116 lines
3.8 KiB
C#
using System;
|
|
using Unity.Collections;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
|
|
namespace Unity.Netcode
|
|
{
|
|
/// <summary>
|
|
/// This is a simple resizable bit vector - i.e., a list of flags that use 1 bit each and can
|
|
/// grow to an indefinite size. This is backed by a NativeList<byte> instead of a single
|
|
/// integer value, allowing it to contain any size of memory. Contains built-in serialization support.
|
|
/// </summary>
|
|
internal struct ResizableBitVector : INetworkSerializable, IDisposable
|
|
{
|
|
private NativeList<byte> m_Bits;
|
|
private const int k_Divisor = sizeof(byte) * 8;
|
|
|
|
public ResizableBitVector(Allocator allocator)
|
|
{
|
|
m_Bits = new NativeList<byte>(allocator);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
m_Bits.Dispose();
|
|
}
|
|
|
|
public int GetSerializedSize()
|
|
{
|
|
return sizeof(int) + m_Bits.Length;
|
|
}
|
|
|
|
private (int, int) GetBitData(int i)
|
|
{
|
|
var index = i / k_Divisor;
|
|
var bitWithinIndex = i % k_Divisor;
|
|
return (index, bitWithinIndex);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set bit 'i' - i.e., bit 0 is 00000001, bit 1 is 00000010, and so on.
|
|
/// There is no upper bound on i except for the memory available in the system.
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
public void Set(int i)
|
|
{
|
|
var (index, bitWithinIndex) = GetBitData(i);
|
|
if (index >= m_Bits.Length)
|
|
{
|
|
m_Bits.Resize(index + 1, NativeArrayOptions.ClearMemory);
|
|
}
|
|
|
|
m_Bits[index] |= (byte)(1 << bitWithinIndex);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unset bit 'i' - i.e., bit 0 is 00000001, bit 1 is 00000010, and so on.
|
|
/// There is no upper bound on i except for the memory available in the system.
|
|
/// Note that once a BitVector has grown to a certain size, it will not shrink back down,
|
|
/// so if you set and unset every bit, it will still serialize at its high watermark size.
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
public void Unset(int i)
|
|
{
|
|
var (index, bitWithinIndex) = GetBitData(i);
|
|
if (index >= m_Bits.Length)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_Bits[index] &= (byte)~(1 << bitWithinIndex);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if bit 'i' is set - i.e., bit 0 is 00000001, bit 1 is 00000010, and so on.
|
|
/// There is no upper bound on i except for the memory available in the system.
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
public bool IsSet(int i)
|
|
{
|
|
var (index, bitWithinIndex) = GetBitData(i);
|
|
if (index >= m_Bits.Length)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return (m_Bits[index] & (byte)(1 << bitWithinIndex)) != 0;
|
|
}
|
|
|
|
public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
|
{
|
|
var length = m_Bits.Length;
|
|
serializer.SerializeValue(ref length);
|
|
m_Bits.ResizeUninitialized(length);
|
|
var ptr = m_Bits.GetUnsafePtr();
|
|
{
|
|
if (serializer.IsReader)
|
|
{
|
|
#if UTP_TRANSPORT_2_0_ABOVE
|
|
serializer.GetFastBufferReader().ReadBytesSafe(ptr, length);
|
|
#else
|
|
serializer.GetFastBufferReader().ReadBytesSafe((byte*)ptr, length);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
#if UTP_TRANSPORT_2_0_ABOVE
|
|
serializer.GetFastBufferWriter().WriteBytesSafe(ptr, length);
|
|
#else
|
|
serializer.GetFastBufferWriter().WriteBytesSafe((byte*)ptr, length);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|