Skip to content
Open
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
3 changes: 2 additions & 1 deletion .yamato/_triggers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ pr_code_changes_checks:
# 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_{{ pinnedTrunk }}
- .yamato/cmb-service-standalone-tests.yml#cmb_service_standalone_test_testproject_ubuntu_il2cpp_{{ pinnedTrunk }}
- .yamato/_run-all.yml#run_all_unified_tests
# The unified (NGO + N4E) tests are no longer a PR check: the unified API is behind N4E's own
# experimental define, so it is not part of what NGO ships. Still run nightly and on "/ci unified".
# Run code coverage test (PRs use the pinned "safe" trunk)
- .yamato/code-coverage.yml#code_coverage_project_test_testproject_ubuntu_{{ pinnedTrunk }}
triggers:
Expand Down
13 changes: 8 additions & 5 deletions .yamato/unified-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
# 2. For all unified editors (currently a single pinned alpha, see project.metafile)

# QUALITY CONSIDERATIONS--------------------------------------------------------------------
# TODO: the manifest swap means testproject/Packages/manifest-unified.json has to be kept in sync
# with manifest.json by hand. Revisit once N4E is a hard dependency of NGO and one manifest
# can cover both cases.
# TODO: N4E is now a hard dependency, so the manifest swap only pins the N4E version and the two
# manifests can be collapsed into one.
# This job is deliberately not part of the PR checks: N4E 7.0.0 ships the unified API behind its own
# experimental define, so nothing in the shipping configuration compiles it.

#------------------------------------------------------------------------------------

Expand All @@ -36,9 +37,11 @@ unified_test_{{ project.name }}_{{ platform.name }}_{{ editor }}:
UNIFIED_TESTS: "true"

commands:
# Swap in the manifest that has the unified packages and versions required.
# Without the N4E package, UNIFIED_NETCODE is undefined and the unified API excluded.
# Swap in the manifest that pins the N4E version the unified API is written against.
- cp {{ project.path }}/Packages/manifest-unified.json {{ project.path }}/Packages/manifest.json
# Turn the unified API on. UNIFIED_NETCODE is opt-in, and N4E keeps its GameObject bridge internal
# until NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL is defined, so both are needed here and nowhere else.
- sed -i "s/UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT/UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT;NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL;UNIFIED_NETCODE;OUT_OF_BAND_RPC/" {{ project.path }}/ProjectSettings/ProjectSettings.asset
- unity-downloader-cli --fast --wait -u {{ editor }} -c Editor
- UnifiedTestRunner --testproject={{ project.path }} --suite=playmode --artifacts-path=test-results --editor-location=.Editor --rerun-strategy=Test --retry={{ num_test_retries }} --clean-library-on-rerun --timeout={{ test_timeout }}
artifacts:
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 @@ -10,6 +10,8 @@ Additional documentation and release notes are available at [Multiplayer Documen

### Added

- Netcode for Entities (`com.unity.netcode` 6.7.0) is now a dependency, so installing Netcode for GameObjects also brings it, and its own dependencies (Entities, Burst, Collections), into the project.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Netcode for Entities (`com.unity.netcode` 6.7.0) is now a dependency, so installing Netcode for GameObjects also brings it, and its own dependencies (Entities, Burst, Collections), into the project.
- Netcode for Entities (`com.unity.netcode` 7.0.0) is now a hard dependency, so installing Netcode for GameObjects also brings it, and its own dependencies (Entities, Burst, Collections), into the project.


### Changed

- Changed `NetworkTransform.UseHalfFloatPrecision` to synchronize position with a resolution of approximately 1mm regardless of how far an object has travelled. Previously the resolution could degrade to approximately 3cm. This does not increase bandwidth, but projects using `NetworkTransform.UseUnreliableDeltas` will send full precision position updates more often. (#4129)
Expand Down
4 changes: 4 additions & 0 deletions com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using System.Collections.Generic;
#if UNIFIED_NETCODE
#if UNIFIED_NETCODE_7_0_0
using Unity.Netcode.Editor;
#else
using Unity.NetCode;
using Unity.NetCode.Editor;
#endif
#endif
using UnityEditor;
using UnityEngine;
using UnityEngine.Scripting.APIUpdating;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.netcode",
"expression": "7.0.0",
"define": "UNIFIED_NETCODE_7_0_0"
},
{
"name": "com.unity.multiplayer.tools",
"expression": "",
Expand All @@ -46,11 +51,6 @@
"expression": "0.2.0",
"define": "MULTIPLAYER_SERVICES_SDK_INSTALLED"
},
{
"name": "com.unity.netcode",
"expression": "1.10.1",
"define": "UNIFIED_NETCODE"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we remove UNIFIED_NETCODE from other places and keep only UNIFIED_NETCODE_7_0_0? I saw other places kept it

},
{
"name": "com.unity.multiplayer.playmode",
"expression": "0.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ namespace Unity.Netcode.Components
/// resulting in a "snap" to the new value if it is different from the anticipated value.</description></item>
///
/// <item><description><b>Smooth:</b> In this mode (with <see cref="StaleDataHandling"/> set to
/// <see cref="Netcode.StaleDataHandling.Ignore"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> callback that calls
/// <see cref="StaleDataHandling.Ignore"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> callback that calls
/// <see cref="Smooth"/> from the anticipated value to the authority value with an appropriate
/// <see cref="Mathf.Lerp"/>-style smooth function), when a more up-to-date value is received from the authority,
/// it will interpolate over time from an incorrect anticipated value to the correct authoritative value.</description></item>
///
/// <item><description><b>Constant Reanticipation:</b> In this mode (with <see cref="StaleDataHandling"/> set to
/// <see cref="Netcode.StaleDataHandling.Reanticipate"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> that calculates a
/// <see cref="StaleDataHandling.Reanticipate"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> that calculates a
/// new anticipated value based on the current authoritative value), when a more up-to-date value is received from
/// the authority, user code calculates a new anticipated value, possibly calling <see cref="Smooth"/> to interpolate
/// between the previous anticipation and the new anticipation. This is useful for values that change frequently and
Expand Down Expand Up @@ -101,11 +101,11 @@ private void Reset()
/// Defines what the behavior should be if we receive a value from the server with an earlier associated
/// time value than the anticipation time value.
/// <br/><br/>
/// If this is <see cref="Netcode.StaleDataHandling.Ignore"/>, the stale data will be ignored and the authoritative
/// If this is <see cref="StaleDataHandling.Ignore"/>, the stale data will be ignored and the authoritative
/// value will not replace the anticipated value until the anticipation time is reached. <see cref="OnAuthoritativeValueChanged"/>
/// and <see cref="OnReanticipate"/> will also not be invoked for this stale data.
/// <br/><br/>
/// If this is <see cref="Netcode.StaleDataHandling.Reanticipate"/>, the stale data will replace the anticipated data and
/// If this is <see cref="StaleDataHandling.Reanticipate"/>, the stale data will replace the anticipated data and
/// <see cref="OnAuthoritativeValueChanged"/> and <see cref="OnReanticipate"/> will be invoked.
/// In this case, the authoritativeTime value passed to <see cref="OnReanticipate"/> will be lower than
/// the anticipationTime value, and that callback can be used to calculate a new anticipated value.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#if UNIFIED_NETCODE
using Unity.Mathematics;
#if !UNIFIED_NETCODE_7_0_0
using Unity.NetCode;
#endif
using Unity.Transforms;
using UnityEngine;

namespace Unity.Netcode
Expand All @@ -13,7 +17,9 @@ namespace Unity.Netcode

[DefaultExecutionOrder(GhostObject.ExecutionOrder + 1)]
//BREAK --- Fix this on UNIFIED side 1st
public partial class NetworkObjectBridge : GhostBehaviour
// Internal: GhostBehaviour is only public when NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL is defined, and a public
// type cannot derive from an internal one.
internal partial class NetworkObjectBridge : GhostBehaviour
{
// DefaultExecutionOrder
// TODO: Define a const for the value used on GhostObject and use that value
Expand Down Expand Up @@ -83,5 +89,45 @@ internal void ApplyScale(Vector3 scale)
Ghost.ApplyPostTransformMatrixScale(scale);
}
}

#if UNIFIED_NETCODE_7_0_0
/// <summary>
/// Stands in for N4E's <c>GhostObject.ApplyPostTransformMatrixScale</c>, which 7.0.0 removed along with the
/// non-uniform scale rework that gave the GameObject-to-entity transform sync ownership of the
/// <see cref="PostTransformMatrix"/>. 6.7.0 still has the method, so this is only compiled against 7.0.0.
/// Remove it once N4E exposes a supported way to push scale to a ghost.
/// </summary>
internal static class GhostObjectScaleExtensions
{
/// <summary>
/// A ghost that replicates 3D scale stores it in its <see cref="PostTransformMatrix"/> and holds
/// <see cref="LocalTransform.Scale"/> at 1, because consumers multiply the two. A ghost authored with
/// <c>UseUniformScale</c> has no matrix - and cannot gain one at runtime, since the component is only in the
/// replicated set when the prefab is registered - so only the uniform scale can be applied there.
/// </summary>
internal static void ApplyPostTransformMatrixScale(this GhostObject ghost, Vector3 scale)
{
var entityManager = ghost.World.EntityManager;
var entity = ghost.Entity;
var localTransform = entityManager.GetComponentData<LocalTransform>(entity);

if (entityManager.HasComponent<PostTransformMatrix>(entity))
{
entityManager.SetComponentData(entity, new PostTransformMatrix { Value = float4x4.Scale(scale) });
localTransform.Scale = 1f;
}
else
{
if (!Mathf.Approximately(scale.x, scale.y) || !Mathf.Approximately(scale.y, scale.z))
{
Debug.LogWarning($"[{nameof(NetworkObjectBridge)}] Non-uniform scale {scale} cannot be replicated by a ghost authored for uniform scale; applying {scale.x} to all axes.", ghost);
}
localTransform.Scale = scale.x;
}

entityManager.SetComponentData(entity, localTransform);
}
}
#endif
}
#endif
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#if UNIFIED_NETCODE && !NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL
#error UNIFIED_NETCODE also requires NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL: Netcode for Entities keeps its GameObject bridge (GhostObject, GhostBehaviour, GhostField) internal until that define is set.
#endif
#if UNIFIED_NETCODE
using System;
using Unity.Entities;
#if !UNIFIED_NETCODE_7_0_0
using Unity.NetCode;
#endif
using UnityEngine;

namespace Unity.Netcode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using System.Collections.Generic;
using Unity.Collections;
using Unity.Entities;
#if !UNIFIED_NETCODE_7_0_0
using Unity.NetCode;
#endif
using UnityEngine;

namespace Unity.Netcode.Components
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ internal void InternalOnNetworkDespawn()
}

/// <summary>
/// In client-server contexts, this method is invoked on both the server and the local client of the owner when <see cref="Netcode.NetworkObject"/> ownership is assigned.
/// In client-server contexts, this method is invoked on both the server and the local client of the owner when <see cref="NetworkObject"/> ownership is assigned.
/// In distributed authority contexts, this method is invoked on all clients connected to the session.
/// </summary>
public virtual void OnGainedOwnership() { }
Expand Down Expand Up @@ -952,7 +952,7 @@ internal void InternalOnOwnershipChanged(ulong previous, ulong current)
}

/// <summary>
/// In client-server contexts, this method is invoked on the local client when it loses ownership of the associated <see cref="Netcode.NetworkObject"/>
/// In client-server contexts, this method is invoked on the local client when it loses ownership of the associated <see cref="NetworkObject"/>
/// and on the server when any client loses ownership.
/// In distributed authority contexts, this method is invoked on all clients connected to the session.
/// </summary>
Expand Down
26 changes: 16 additions & 10 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
using Unity.Collections;
#if UNIFIED_NETCODE
using Unity.Entities;
// Netcode for Entities' namespace differs from this one only by the casing of a single letter, so a
// blanket import of it competes with Unity.Netcode on every name the two happen to share. Importing
// only the types used here keeps that surface to exactly those names.
using NetCodeConfig = Unity.NetCode.NetCodeConfig;
// N4E's own Netcode class cannot be aliased as "Netcode": inside namespace Unity.Netcode that name
// resolves to the enclosing Unity.Netcode namespace before any file-scope alias is considered, so it gets
// its own name here. 6.7.0 additionally keeps the config and world types under the older Unity.NetCode
// casing, aliased to the 7.0.0 spellings so the use sites below read the same either way.
#if UNIFIED_NETCODE_7_0_0
using EntitiesNetcode = Unity.Netcode.Netcode;
#else
using EntitiesNetcode = Unity.NetCode.Netcode;
using NetcodeConfig = Unity.NetCode.NetCodeConfig;
using NetcodeWorld = Unity.NetCode.NetcodeWorld;
#endif
#endif
using Unity.Netcode.Components;
using Unity.Netcode.GameObjects.Timing;
using Unity.Netcode.Logging;
Expand Down Expand Up @@ -1375,13 +1381,13 @@ internal void InitializeNetcodeWorld()

if (this == Singleton)
{
if (NetCode.Netcode.IsActive)
if (EntitiesNetcode.IsActive)
{
Log.Info(new Context(LogLevel.Normal, "Netcode is not active but has an instance at this point."));
}
/// !! Important !!
/// Clear out any pre-existing configuration in the event this applicatioin instance has already been connected to a session.
NetCode.Netcode.Reset();
EntitiesNetcode.Reset();
}

/// !! Initialize worlds here !!
Expand All @@ -1396,14 +1402,14 @@ internal void InitializeNetcodeWorld()
/// <returns>True if the configuration is correct; otherwise, false.</returns>
private bool UnifiedIsConfiguredCorrectly()
{
if (NetCodeConfig.Global == null)
if (NetcodeConfig.Global == null)
{
Log.Error(new Context(LogLevel.Error, $"You must create a {nameof(NetCodeConfig)} and set it to a single world in order to run in hybrid mode!").AddTag("Unified"));
Log.Error(new Context(LogLevel.Error, $"You must create a {nameof(NetcodeConfig)} and set it to a single world in order to run in hybrid mode!").AddTag("Unified"));
return false;
}
if (NetCodeConfig.Global.HostWorldModeSelection != NetCodeConfig.HostWorldMode.SingleWorld)
if (NetcodeConfig.Global.HostWorldModeSelection != NetcodeConfig.HostWorldMode.SingleWorld)
{
Log.Error(new Context(LogLevel.Error, $"You must configure {nameof(NetCodeConfig)} to only use a single world in order to run in hybrid mode!").AddTag("Unified"));
Log.Error(new Context(LogLevel.Error, $"You must configure {nameof(NetcodeConfig)} to only use a single world in order to run in hybrid mode!").AddTag("Unified"));
return false;
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Unity.Netcode.Components;
using Unity.Netcode.Logging;
using Unity.Netcode.Runtime;
#if UNIFIED_NETCODE
#if UNIFIED_NETCODE && !UNIFIED_NETCODE_7_0_0
using Unity.NetCode;
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ public enum StaleDataHandling
/// <list type="bullet">
///
/// <item><description><b>Snap:</b> In this mode (with <see cref="StaleDataHandling"/> set to
/// <see cref="Netcode.StaleDataHandling.Ignore"/> and no <see cref="NetworkBehaviour.OnReanticipate"/> callback),
/// <see cref="StaleDataHandling.Ignore"/> and no <see cref="NetworkBehaviour.OnReanticipate"/> callback),
/// the moment a more up-to-date value is received from the authority, it will simply replace the anticipated value,
/// resulting in a "snap" to the new value if it is different from the anticipated value.</description></item>
///
/// <item><description><b>Smooth:</b> In this mode (with <see cref="StaleDataHandling"/> set to
/// <see cref="Netcode.StaleDataHandling.Ignore"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> callback that calls
/// <see cref="StaleDataHandling.Ignore"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> callback that calls
/// <see cref="Smooth"/> from the anticipated value to the authority value with an appropriate
/// <see cref="Mathf.Lerp"/>-style smooth function), when a more up-to-date value is received from the authority,
/// it will interpolate over time from an incorrect anticipated value to the correct authoritative value.</description></item>
///
/// <item><description><b>Constant Reanticipation:</b> In this mode (with <see cref="StaleDataHandling"/> set to
/// <see cref="Netcode.StaleDataHandling.Reanticipate"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> that calculates a
/// <see cref="StaleDataHandling.Reanticipate"/> and an <see cref="NetworkBehaviour.OnReanticipate"/> that calculates a
/// new anticipated value based on the current authoritative value), when a more up-to-date value is received from
/// the authority, user code calculates a new anticipated value, possibly calling <see cref="Smooth"/> to interpolate
/// between the previous anticipation and the new anticipation. This is useful for values that change frequently and
Expand Down Expand Up @@ -85,11 +85,11 @@ public class AnticipatedNetworkVariable<T> : NetworkVariableBase
/// Defines what the behavior should be if we receive a value from the server with an earlier associated
/// time value than the anticipation time value.
/// <br/><br/>
/// If this is <see cref="Netcode.StaleDataHandling.Ignore"/>, the stale data will be ignored and the authoritative
/// If this is <see cref="StaleDataHandling.Ignore"/>, the stale data will be ignored and the authoritative
/// value will not replace the anticipated value until the anticipation time is reached. <see cref="OnAuthoritativeValueChanged"/>
/// and <see cref="NetworkBehaviour.OnReanticipate"/> will also not be invoked for this stale data.
/// <br/><br/>
/// If this is <see cref="Netcode.StaleDataHandling.Reanticipate"/>, the stale data will replace the anticipated data and
/// If this is <see cref="StaleDataHandling.Reanticipate"/>, the stale data will replace the anticipated data and
/// <see cref="OnAuthoritativeValueChanged"/> and <see cref="NetworkBehaviour.OnReanticipate"/> will be invoked.
/// In this case, the authoritativeTime value passed to <see cref="NetworkBehaviour.OnReanticipate"/> will be lower than
/// the anticipationTime value, and that callback can be used to calculate a new anticipated value.
Expand Down Expand Up @@ -229,7 +229,7 @@ public void Anticipate(T value)
/// Retrieves or sets the underlying authoritative value.
/// Note that only a client or server with write permissions to this variable may set this value.
/// When this variable has been anticipated, this value will alawys return the most recent authoritative
/// state, which is updated even if <see cref="StaleDataHandling"/> is <see cref="Netcode.StaleDataHandling.Ignore"/>.
/// state, which is updated even if <see cref="StaleDataHandling"/> is <see cref="StaleDataHandling.Ignore"/>.
/// </summary>
#pragma warning restore IDE0001
public T AuthoritativeValue
Expand Down
Loading
Loading