Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .yamato/_triggers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ pr_code_changes_checks:
# Coverage on other standalone machines is present in Nightly job so it's enough to not run all of them for PRs
# desktop_standalone_test and cmb_service_standalone_test are both reusing desktop_standalone_build dependency so we run those in the same configuration on PRs to reduce waiting time.
# Note that our daily tests will anyway run both test configurations in "minimal supported" and "trunk" configurations
- .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_trunk
- .yamato/cmb-service-standalone-tests.yml#cmb_service_standalone_test_testproject_ubuntu_il2cpp_trunk

# TODO: Move these tests back to trunk once CMB Service has addressed https://jira.unity3d.com/browse/MTTB-1680
- .yamato/desktop-standalone-tests.yml#desktop_standalone_test_testproject_ubuntu_il2cpp_6000.4
- .yamato/cmb-service-standalone-tests.yml#cmb_service_standalone_test_testproject_ubuntu_il2cpp_6000.4
triggers:
expression: |-
(pull_request.comment eq "ngo" OR
Expand Down
1 change: 1 addition & 0 deletions .yamato/project.metafile
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ validation_editors:
- 6000.0
- 6000.2
- 6000.3
- 6000.4
- trunk
minimal:
- 6000.0
Expand Down
2 changes: 2 additions & 0 deletions com.unity.netcode.gameobjects/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
### Added

- Added NetworkRigidbody documentation section. (#3664)
- Added new fields to the `SceneMap` struct when using Unity 6.3 or higher. These fields allow referencing scene handles via the new `SceneHandle` struct. (#3734)

### Changed

Expand All @@ -24,6 +25,7 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Deprecated

- On Unity 6.5 some `SceneMap` fields that use an `int` to represent a `SceneHandle` are deprecated. (#3734)

### Removed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReade
var reader = serializer.GetFastBufferReader();
// DANGO-TODO Rust needs to be updated to either handle this ulong or to remove the scene store.
#if SCENE_MANAGEMENT_SCENE_HANDLE_MUST_USE_ULONG
reader.ReadValue(out ulong rawData);
reader.ReadValueSafe(out ulong rawData);
m_Handle = SceneHandle.FromRawData(rawData);
#elif SCENE_MANAGEMENT_SCENE_HANDLE_NO_INT_CONVERSION
reader.ReadValueSafe(out int rawData);
Expand Down Expand Up @@ -92,8 +92,14 @@ internal NetworkSceneHandle(int handle, bool asMock)
/// <summary>
/// Implicit conversion from <see cref="SceneHandle"/> to <see cref="NetworkSceneHandle"/>.
/// </summary>
/// <param name="handle"></param>
/// <param name="handle">The SceneHandle to covert</param>
public static implicit operator NetworkSceneHandle(SceneHandle handle) => new(handle);

/// <summary>
/// Implicit conversion from <see cref="NetworkSceneHandle"/> to <see cref="SceneHandle"/>.
/// </summary>
/// <param name="handle">The NetworkSceneHandle to convert</param>
public static implicit operator SceneHandle(NetworkSceneHandle handle) => handle.m_Handle;
#else
/// <summary>
/// Implicit conversion from <see langword="int"/> to <see cref="NetworkSceneHandle"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3115,19 +3115,101 @@ public struct SceneMap : INetworkSerializable
/// The name of the scene
/// </summary>
public string SceneName;

#if SCENE_MANAGEMENT_SCENE_HANDLE_NO_INT_CONVERSION
/// <summary>
/// The scene's server handle (a.k.a network scene handle)
/// </summary>
/// <remarks>
/// This is deprecated in favor of ServerSceneHandle
/// </remarks>
[Obsolete("Int representation of a SceneHandle is deprecated, please use SceneHandle instead.")]
#else
/// <summary>
/// The scene's server handle (a.k.a network scene handle)
/// </summary>
#endif
public int ServerHandle;

#if SCENE_MANAGEMENT_SCENE_HANDLE_NO_INT_CONVERSION
/// <summary>
/// The mapped handled. This could be the ServerHandle or LocalHandle depending upon context (client or server).
/// </summary>
/// <remarks>
/// This is deprecated in favor of MappedLocalSceneHandle
/// </remarks>
[Obsolete("Int representation of a SceneHandle is deprecated, please use SceneHandle instead.")]
#else
/// <summary>
/// The mapped handled. This could be the ServerHandle or LocalHandle depending upon context (client or server).
/// </summary>
#endif
public int MappedLocalHandle;

#if SCENE_MANAGEMENT_SCENE_HANDLE_NO_INT_CONVERSION
/// <summary>
/// The local handle of the scene.
/// </summary>
/// <remarks>
/// This is deprecated in favor of LocalSceneHandle
/// </remarks>
[Obsolete("Int representation of a SceneHandle is deprecated, please use SceneHandle instead.")]
#else
/// <summary>
/// The local handle of the scene.
/// </summary>
#endif
public int LocalHandle;

#if SCENE_MANAGEMENT_SCENE_HANDLE_AVAILABLE
/// <summary>
/// The scene's server handle (a.k.a network scene handle)
/// </summary>
public SceneHandle ServerSceneHandle;
/// <summary>
/// The mapped handled. This could be the ServerSceneHandle or LocalSceneHandle depending upon context (client or server).
/// </summary>
public SceneHandle MappedLocalSceneHandle;
/// <summary>
/// The local handle of the scene.
/// </summary>
public SceneHandle LocalSceneHandle;
#endif

private NetworkSceneHandle m_ServerHandle;
private NetworkSceneHandle m_MappedLocalHandle;
private NetworkSceneHandle m_LocalHandle;

internal SceneMap(MapTypes mapType, Scene scene, bool isScenePresent, NetworkSceneHandle serverHandle, NetworkSceneHandle mappedLocalHandle)
{
MapType = mapType;
Scene = scene;
ScenePresent = isScenePresent;
SceneName = isScenePresent ? scene.name : "Not Present";

m_ServerHandle = serverHandle;
m_MappedLocalHandle = mappedLocalHandle;
m_LocalHandle = new NetworkSceneHandle(scene.handle);

#if SCENE_MANAGEMENT_SCENE_HANDLE_AVAILABLE
ServerSceneHandle = serverHandle;
MappedLocalSceneHandle = mappedLocalHandle;
LocalSceneHandle = scene.handle;
#endif

#pragma warning disable CS0618 // Type or member is obsolete
#if SCENE_MANAGEMENT_SCENE_HANDLE_MUST_USE_ULONG
ServerHandle = (int)m_ServerHandle.GetRawData();
MappedLocalHandle = (int)m_MappedLocalHandle.GetRawData();
LocalHandle = (int)m_LocalHandle.GetRawData();
#else
ServerHandle = m_ServerHandle.GetRawData();
MappedLocalHandle = m_MappedLocalHandle.GetRawData();
LocalHandle = m_LocalHandle.GetRawData();
#endif
#pragma warning restore CS0618 // Type or member is obsolete
}

/// <inheritdoc cref="INetworkSerializable.NetworkSerialize{T}(BufferSerializer{T})"/>
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
Expand All @@ -3140,11 +3222,45 @@ public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReade
if (ScenePresent)
{
serializer.SerializeValue(ref SceneName);
#pragma warning disable CS0618 // Type or member is obsolete
serializer.SerializeValue(ref LocalHandle);

}
serializer.SerializeValue(ref ServerHandle);
serializer.SerializeValue(ref MappedLocalHandle);
#pragma warning restore CS0618 // Type or member is obsolete


#if SCENE_MANAGEMENT_SCENE_HANDLE_AVAILABLE
// Ensure the SceneHandles are valid to be serialized
if (serializer.IsWriter)
{
if (m_LocalHandle.IsEmpty() && LocalSceneHandle != SceneHandle.None)
{
m_LocalHandle = LocalSceneHandle;
}
if (m_ServerHandle.IsEmpty() && ServerSceneHandle != SceneHandle.None)
{
m_ServerHandle = ServerSceneHandle;
}
if (m_MappedLocalHandle.IsEmpty() && MappedLocalSceneHandle != SceneHandle.None)
{
m_MappedLocalHandle = MappedLocalSceneHandle;
}
}

// Serialize the INetworkSerializable representations
serializer.SerializeValue(ref m_LocalHandle);
serializer.SerializeValue(ref m_ServerHandle);
serializer.SerializeValue(ref m_MappedLocalHandle);

// If we're reading, convert back into the raw SceneHandle
if (serializer.IsReader)
{
ServerSceneHandle = m_ServerHandle;
ServerSceneHandle = m_LocalHandle;
ServerSceneHandle = m_MappedLocalHandle;
}
#endif
}
}

Expand All @@ -3156,43 +3272,14 @@ public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReade
public List<SceneMap> GetSceneMapping(MapTypes mapType)
{
var mapping = new List<SceneMap>();
if (mapType == MapTypes.ServerToClient)
{
foreach (var entry in ServerSceneHandleToClientSceneHandle)
{
var scene = ScenesLoaded[entry.Value];
var sceneIsPresent = scene.IsValid() && scene.isLoaded;
var sceneMap = new SceneMap()
{
MapType = mapType,
ServerHandle = entry.Key.GetRawData(),
MappedLocalHandle = entry.Value.GetRawData(),
LocalHandle = new NetworkSceneHandle(scene.handle).GetRawData(),
Scene = scene,
ScenePresent = sceneIsPresent,
SceneName = sceneIsPresent ? scene.name : "NotPresent",
};
mapping.Add(sceneMap);
}
}
else
var map = mapType == MapTypes.ServerToClient ? ServerSceneHandleToClientSceneHandle : ClientSceneHandleToServerSceneHandle;

foreach (var entry in map)
{
foreach (var entry in ClientSceneHandleToServerSceneHandle)
{
var scene = ScenesLoaded[entry.Key];
var sceneIsPresent = scene.IsValid() && scene.isLoaded;
var sceneMap = new SceneMap()
{
MapType = mapType,
ServerHandle = entry.Key.GetRawData(),
MappedLocalHandle = entry.Value.GetRawData(),
LocalHandle = new NetworkSceneHandle(scene.handle).GetRawData(),
Scene = scene,
ScenePresent = sceneIsPresent,
SceneName = sceneIsPresent ? scene.name : "NotPresent",
};
mapping.Add(sceneMap);
}
var scene = ScenesLoaded[entry.Key];
var sceneIsPresent = scene.IsValid() && scene.isLoaded;
var sceneMap = new SceneMap(mapType, scene, sceneIsPresent, entry.Key, entry.Value);
mapping.Add(sceneMap);
}

return mapping;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using NUnit.Framework;
using Unity.Collections;

namespace Unity.Netcode.EditorTests
{
internal class NetworkSceneHandleTests
{
[Test]
public void NetworkSceneHandleSerializationTest()
{
var handle = new NetworkSceneHandle(1234, true);

using var writer = new FastBufferWriter(sizeof(ulong), Allocator.Temp);
Assert.That(writer.Position, Is.EqualTo(0), "Writer position should be zero");

writer.WriteNetworkSerializable(handle);
#if SCENE_MANAGEMENT_SCENE_HANDLE_MUST_USE_ULONG
Assert.That(writer.Position, Is.EqualTo(sizeof(ulong)), $"Writer position should not be beyond size! Expected: {sizeof(ulong)} Actual: {writer.Position}");
#else
Assert.That(writer.Position, Is.EqualTo(sizeof(int)), $"Writer position should not be beyond size! Expected: {sizeof(int)} Actual: {writer.Position}");
#endif

var reader = new FastBufferReader(writer, Allocator.Temp);
Assert.That(reader.Position, Is.EqualTo(0), "Reader position should be zero");
reader.ReadNetworkSerializable(out NetworkSceneHandle deserializedHandle);
#if SCENE_MANAGEMENT_SCENE_HANDLE_MUST_USE_ULONG
Assert.That(reader.Position, Is.EqualTo(sizeof(ulong)), $"Reader position should not be beyond size! Expected: {sizeof(ulong)} Actual: {reader.Position}");
#else
Assert.That(reader.Position, Is.EqualTo(sizeof(int)), $"Reader position should not be beyond size! Expected: {sizeof(int)} Actual: {reader.Position}");
#endif

Assert.AreEqual(handle, deserializedHandle);

// Now serialize a list of SceneHandles
var handles = new NetworkSceneHandle[] { handle, new NetworkSceneHandle(4567, true), new NetworkSceneHandle(7890, true) };

using var listWriter = new FastBufferWriter(1024, Allocator.Temp);

Assert.That(listWriter.Position, Is.EqualTo(0), "Writer position should be zero");

listWriter.WriteNetworkSerializable(handles);
#if SCENE_MANAGEMENT_SCENE_HANDLE_MUST_USE_ULONG
var expectedSize = sizeof(int) + (sizeof(ulong) * handles.Length);
#else
var expectedSize = sizeof(int) + (sizeof(int) * handles.Length);
#endif
Assert.That(listWriter.Position, Is.EqualTo(expectedSize), $"Writer position should not be beyond size! Expected: {expectedSize} Actual: {listWriter.Position}");

var listReader = new FastBufferReader(listWriter, Allocator.Temp);
Assert.That(listReader.Position, Is.EqualTo(0), "Reader position should be zero");
listReader.ReadNetworkSerializable(out NetworkSceneHandle[] deserializedHandleList);
Assert.That(listReader.Position, Is.EqualTo(expectedSize), $"Reader position should not be beyond expected size! Expected: {expectedSize} Actual: {listReader.Position}");

Assert.AreEqual(handles, deserializedHandleList);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@
"name": "Unity",
"expression": "6000.1.0a1",
"define": "HOSTNAME_RESOLUTION_AVAILABLE"
},
{
"name": "Unity",
"expression": "6000.4.0a3",
"define": "SCENE_MANAGEMENT_SCENE_HANDLE_NO_INT_CONVERSION"
},
{
"name": "Unity",
"expression": "6000.5.0a1",
"define": "SCENE_MANAGEMENT_SCENE_HANDLE_MUST_USE_ULONG"
}
],
"noEngineReferences": false
Expand Down