diff --git a/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs b/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs index 922ac007f2..2b64466e27 100644 --- a/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs +++ b/com.unity.netcode.gameobjects/Editor/NetworkObjectEditor.cs @@ -2,6 +2,10 @@ #if BYPASS_DEFAULT_ENUM_DRAWER && MULTIPLAYER_SERVICES_SDK_INSTALLED using System.Linq; #endif +#if UNIFIED_NETCODE +using Unity.NetCode; +using Unity.NetCode.Editor; +#endif using UnityEditor; using UnityEngine; @@ -23,6 +27,34 @@ public class NetworkObjectEditor : UnityEditor.Editor private static readonly string[] k_HiddenFields = { "m_Script" }; +#if UNIFIED_NETCODE + /// + /// Register for the GhostAdapter removal event. + /// + [InitializeOnLoadMethod] + private static void OnApplicationStart() + { + GhostAdapterEditor.OnGhostAdapterPreRemoval = OnGhostAdapterPreRemoval; + } + + /// + /// Callback to remove the GhostBehaviours prior to removing GhostAdapter. + /// + /// The with the component being removed. + private static void OnGhostAdapterPreRemoval(GameObject gameObject) + { + var ghostBehaviours = gameObject.GetComponentsInChildren(); + for (int i = ghostBehaviours.Length - 1; i >= 0; i--) + { + DestroyImmediate(ghostBehaviours[i], true); + } + var networkObject = gameObject.GetComponent(); + networkObject.GhostAdapter = null; + networkObject.HasGhost = false; + networkObject.HadBridge = true; + } +#endif + private void Initialize() { if (m_Initialized) diff --git a/com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs b/com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs index 06823d94e2..1fcb77f709 100644 --- a/com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs +++ b/com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs @@ -1,3 +1,4 @@ +using System.Runtime.CompilerServices; using Unity.Netcode.Components; using UnityEditor; using UnityEngine; @@ -94,9 +95,40 @@ public override void OnEnable() base.OnEnable(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void SetGUIActive(bool active = true) + { +#if UNIFIED_NETCODE + if (Application.IsPlaying(m_NetworkObject) && m_NetworkObject.HasGhost) + { + GUI.enabled = false; + } + else + { + GUI.enabled = active; + } +#else + GUI.enabled = active; +#endif + + } + + private NetworkObject m_NetworkObject; + private void DisplayNetworkTransformProperties() { var networkTransform = target as NetworkTransform; + +#if UNIFIED_NETCODE + m_NetworkObject = networkTransform.GetComponent(); + var hasGhost = m_NetworkObject.HasGhost; + SetGUIActive(); +#else +#if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D + var hasGhost = false; +#endif +#endif + EditorGUILayout.LabelField("Axis to Synchronize", EditorStyles.boldLabel); { GUILayout.BeginHorizontal(); @@ -190,7 +222,7 @@ private void DisplayNetworkTransformProperties() { networkTransform.UseUnreliableDeltas = false; } - GUI.enabled = !networkTransform.SwitchTransformSpaceWhenParented; + SetGUIActive(!networkTransform.SwitchTransformSpaceWhenParented); if (networkTransform.SwitchTransformSpaceWhenParented) { EditorGUILayout.BeginHorizontal(); @@ -202,11 +234,13 @@ private void DisplayNetworkTransformProperties() { EditorGUILayout.PropertyField(m_UseUnreliableDeltas); } - GUI.enabled = true; + + SetGUIActive(true); EditorGUILayout.Space(); EditorGUILayout.LabelField("Configurations", EditorStyles.boldLabel); - GUI.enabled = !networkTransform.UseUnreliableDeltas; + + SetGUIActive(!networkTransform.UseUnreliableDeltas); if (networkTransform.UseUnreliableDeltas) { EditorGUILayout.BeginHorizontal(); @@ -218,7 +252,7 @@ private void DisplayNetworkTransformProperties() { EditorGUILayout.PropertyField(m_SwitchTransformSpaceWhenParented); } - GUI.enabled = true; + SetGUIActive(true); if (m_SwitchTransformSpaceWhenParented.boolValue) { m_TickSyncChildren.boolValue = true; @@ -297,20 +331,23 @@ private void DisplayNetworkTransformProperties() #if COM_UNITY_MODULES_PHYSICS // if rigidbody is present but network rigidbody is not present - if (networkTransform.TryGetComponent(out _) && networkTransform.TryGetComponent(out _) == false) + if (hasGhost && networkTransform.TryGetComponent(out _) && networkTransform.TryGetComponent(out _) == false) { - EditorGUILayout.HelpBox("This GameObject contains a Rigidbody but no NetworkRigidbody.\n" + + EditorGUILayout.HelpBox("This GameObject contains a Rigidbody but no NetworkRigidbody.\n " + "Add a NetworkRigidbody component to improve Rigidbody synchronization.", MessageType.Warning); } #endif // COM_UNITY_MODULES_PHYSICS #if COM_UNITY_MODULES_PHYSICS2D - if (networkTransform.TryGetComponent(out _) && networkTransform.TryGetComponent(out _) == false) + if (!hasGhost && networkTransform.TryGetComponent(out _) && networkTransform.TryGetComponent(out _) == false) { EditorGUILayout.HelpBox("This GameObject contains a Rigidbody2D but no NetworkRigidbody2D.\n" + "Add a NetworkRigidbody2D component to improve Rigidbody2D synchronization.", MessageType.Warning); } #endif // COM_UNITY_MODULES_PHYSICS2D +#if UNIFIED_NETCODE + GUI.enabled = true; +#endif } /// diff --git a/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef b/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef index e4d210bd4d..9ef9dac45f 100644 --- a/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef +++ b/com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef @@ -8,7 +8,8 @@ "Unity.Networking.Transport", "Unity.Services.Core", "Unity.Services.Authentication", - "Unity.NetCode" + "Unity.NetCode", + "Unity.NetCode.Editor" ], "includePlatforms": [ "Editor" diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs index fcd585d9a9..93a36cc760 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs @@ -1,8 +1,5 @@ #if UNIFIED_NETCODE using Unity.NetCode; -#if UNITY_EDITOR -using UnityEditor; -#endif using UnityEngine; namespace Unity.Netcode @@ -13,31 +10,49 @@ namespace Unity.Netcode /// the N4E-spawned hybrid prefab instances to the incoming /// specific to the N4E-spawned hybrid prefab instance that has the matching . /// + + [DefaultExecutionOrder(GhostAdapterExecutionOrder.ExecutionOrder + 1)] + //BREAK --- Fix this on UNIFIED side 1st public partial class NetworkObjectBridge : GhostBehaviour { + // DefaultExecutionOrder + // TODO: Define a const for the value used on GhostAdapter and use that value + // to set the execution order so if it changes on GhostAdapter it updates here. #if UNITY_EDITOR - [HideInInspector] - [SerializeField] - private bool m_Sorted = false; private void OnValidate() { - // TODO-UNIFIED: GhostAdapter must be above all GhostBehaviours in order to assure the GhostAdapter is initialized before any GhostBehaviour. - // This auto-sorting is required because the GhostBehaviours rely on the GhostAdapter.Awake being invoked before any GhostBehaviour.Awake. - if (!m_Sorted && !EditorApplication.isPlaying) + hideFlags = HideFlags.HideInInspector; + + var ghostAdapter = GetComponent(); + if (ghostAdapter == null) { - while (UnityEditorInternal.ComponentUtility.MoveComponentUp(this)) - { - // Keep moving until it can't go higher - } - var ghostAdapter = gameObject.GetComponent(); - // Now move the GhostAdapter to the top so it is above NetworkObjectBridge - while (ghostAdapter != null && UnityEditorInternal.ComponentUtility.MoveComponentUp(ghostAdapter)) + return; + } + + // Start users with just interpolation (they can adjust this if they want prediction) + // to make the initial transition less problematic for users. + ghostAdapter.SupportedGhostModes = GhostModeMask.Interpolated; + +#if COM_UNITY_MODULES_PHYSICS + var rigidBody = GetComponent(); + var ghostRigidBody = GetComponent(); + if (rigidBody != null) + { + // This must be enabled when replicating the rigid body. + + ghostAdapter.SingleWorldHostInterpolationSmoothing = SingleWorldHostInterpolationMode.Interpolate; + // TODO: Currently, this is added only if you enable replication of the rigid body. + // There is a bug where if you don't add this component it doesn't synchronize the transform. + // Remove this once the issue is resolved. + if (ghostRigidBody == null) { - // Keep moving until it can't go higher + gameObject.AddComponent(); } - - m_Sorted = true; } +#endif +#if COM_UNITY_MODULES_PHYSICS2D + // TODO: Fill out a similar script as above but for the 2D version +#endif } #endif @@ -67,6 +82,11 @@ internal void HybridParentUpdate(Vector3 scale) //Debug.Log($"---- New LT: {transform.localPosition} | {transform.localRotation}"); Ghost.ApplyPostTransformMatrixScale(scale); } + + internal void ApplyScale(Vector3 scale) + { + Ghost.ApplyPostTransformMatrixScale(scale); + } } } #endif diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs index f1a8d7dc3c..8b99dce5aa 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedBootstrap.cs @@ -64,16 +64,6 @@ public override bool Initialize(string defaultWorldName) } networkManager.NetcodeWorld = (NetcodeWorld)LastCreatedWorld; -#if UNIFIED_NGO_REGISTERS_PREFABS - if (networkManager.NetworkConfig.Prefabs.HasPendingGhostPrefabs) - { - if (networkManager.LogLevel <= LogLevel.Developer) - { - NetworkLog.LogInfo($"[{nameof(UnifiedBootstrap)}] Registering hybrid prefabs..."); - } - networkManager.NetworkConfig.Prefabs.RegisterGhostPrefabs(networkManager); - } -#endif } else { diff --git a/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs b/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs index 97eabd16ab..9fdfffbd38 100644 --- a/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs +++ b/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs @@ -47,11 +47,6 @@ public class NetworkPrefabs [NonSerialized] private List m_Prefabs = new List(); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - [NonSerialized] - internal Dictionary PrefabTable = new Dictionary(); -#endif - [NonSerialized] private List m_RuntimeAddedPrefabs = new List(); @@ -62,18 +57,12 @@ private void AddTriggeredByNetworkPrefabList(NetworkPrefab networkPrefab) // Don't add this to m_RuntimeAddedPrefabs // This prefab is now in the PrefabList, so if we shutdown and initialize again, we'll pick it up from there. m_Prefabs.Add(networkPrefab); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - PrefabTable.TryAdd(networkPrefab.SourcePrefabGlobalObjectIdHash, networkPrefab); -#endif } } private void RemoveTriggeredByNetworkPrefabList(NetworkPrefab networkPrefab) { m_Prefabs.Remove(networkPrefab); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - PrefabTable.Remove(networkPrefab.SourcePrefabGlobalObjectIdHash); -#endif } /// @@ -106,9 +95,6 @@ public void Initialize(bool warnInvalid = true) { m_Prefabs.Clear(); NetworkPrefabsLists.RemoveAll(x => x == null); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - PrefabTable.Clear(); -#endif foreach (var list in NetworkPrefabsLists) { list.OnAdd += AddTriggeredByNetworkPrefabList; @@ -141,16 +127,10 @@ public void Initialize(bool warnInvalid = true) if (AddPrefabRegistration(networkPrefab)) { m_Prefabs.Add(networkPrefab); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - PrefabTable.TryAdd(networkPrefab.SourcePrefabGlobalObjectIdHash, networkPrefab); -#endif } else { removeList?.Add(networkPrefab); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - PrefabTable.Remove(networkPrefab.SourcePrefabGlobalObjectIdHash); -#endif } } @@ -159,16 +139,10 @@ public void Initialize(bool warnInvalid = true) if (AddPrefabRegistration(networkPrefab)) { m_Prefabs.Add(networkPrefab); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - PrefabTable.TryAdd(networkPrefab.SourcePrefabGlobalObjectIdHash, networkPrefab); -#endif } else { removeList?.Add(networkPrefab); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - PrefabTable.Remove(networkPrefab.SourcePrefabGlobalObjectIdHash); -#endif } } @@ -201,9 +175,6 @@ public bool Add(NetworkPrefab networkPrefab) { m_Prefabs.Add(networkPrefab); m_RuntimeAddedPrefabs.Add(networkPrefab); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - PrefabTable.TryAdd(networkPrefab.SourcePrefabGlobalObjectIdHash, networkPrefab); -#endif return true; } @@ -231,9 +202,6 @@ public void Remove(NetworkPrefab prefab) m_RuntimeAddedPrefabs.Remove(prefab); OverrideToNetworkPrefab.Remove(prefab.TargetPrefabGlobalObjectIdHash); NetworkPrefabOverrideLinks.Remove(prefab.SourcePrefabGlobalObjectIdHash); -#if UNIFIED_NETCODE && UNIFIED_NGO_REGISTERS_PREFABS - PrefabTable.Remove(prefab.SourcePrefabGlobalObjectIdHash); -#endif } /// @@ -311,50 +279,6 @@ public bool Contains(NetworkPrefab prefab) #if UNIFIED_NETCODE internal bool HasGhostPrefabs { get; private set; } - -#if UNIFIED_NGO_REGISTERS_PREFABS - /// - /// TODO: Either keep or remove prior to freeze. - /// Leaving this here in case we have to control when things get registered. - /// - internal bool HasPendingGhostPrefabs { get; private set; } - private List m_PendingGhostRegistration = new List(); - /// - /// UNIFIED-POC
- /// Hybrid NetworkObject-Ghost Prefab Registration
- ///
- /// - /// When is true, s - /// will mark themselves as having a ghost during . - /// After validation, if a network prefab's value is - /// set, then it is added to . - /// Within during the , - /// if is true then will be invoked. - /// This will repeat until the hosted single world instance is created. - /// - /// - internal void RegisterGhostPrefabs(NetworkManager networkManager) - { - if (!HasPendingGhostPrefabs) - { - Debug.LogWarning($"Should not be invoking!"); - return; - } - var isHost = networkManager.IsHost; - for (int i = m_PendingGhostRegistration.Count - 1; i >= 0; i--) - { - var networkPrefab = m_PendingGhostRegistration[i]; - - // Returns false if the single world is not available yet - if (NetCode.Netcode.RegisterPrefabSingleWorld(networkPrefab.Prefab, isHost, networkManager.NetcodeWorld)) - { - Debug.Log($"[{nameof(NetworkPrefabs)}][{nameof(RegisterGhostPrefabs)}] Registered hybrid spawned object: {networkPrefab.Prefab.name}"); - m_PendingGhostRegistration.RemoveAt(i); - } - } - HasPendingGhostPrefabs = m_PendingGhostRegistration.Count > 0; - } -#endif #endif @@ -380,11 +304,6 @@ private bool AddPrefabRegistration(NetworkPrefab networkPrefab) if (networkPrefab.HasGhost) { HasGhostPrefabs = true; - -#if UNIFIED_NGO_REGISTERS_PREFABS - HasPendingGhostPrefabs = true; - m_PendingGhostRegistration.TryAdd(networkPrefab); -#endif } #endif diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs index e9c4fe4693..f9a1eed8a4 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs @@ -370,17 +370,38 @@ private void CheckForInScenePlaced() [SerializeField] internal bool HadBridge; #if UNITY_EDITOR + private void OnApplicationUpdate() + { + NetworkObjectBridge = gameObject.AddComponent(); + HadBridge = true; + // Transform synchronization is handled by unified netcode + SynchronizeTransform = false; + + EditorApplication.update -= OnApplicationUpdate; + } + internal void UnifiedValidation() { NetworkObjectBridge = GetComponent(); GhostAdapter = GetComponent(); + HasGhost = GhostAdapter != null; - if (HasGhost && NetworkObjectBridge == null) + if (HasGhost) { - NetworkObjectBridge = gameObject.AddComponent(); - HadBridge = true; - // Transform synchronization is handled by unified netcode - SynchronizeTransform = false; + //TODO: Needs to be validated once develop-2.0.0 is merged. + if (InScenePlaced) + { + Debug.LogError($"This experimental version of NGO does not support hybrid in-scene placed objects."); + Destroy(GhostAdapter); + HasGhost = false; + return; + } + + if (NetworkObjectBridge == null) + { + EditorApplication.update -= OnApplicationUpdate; + EditorApplication.update += OnApplicationUpdate; + } } else if (HadBridge && !HasGhost && !NetworkObjectBridge) { @@ -389,6 +410,14 @@ internal void UnifiedValidation() } } #endif + + public void ApplyScale(Vector3 scale) + { + if (HasGhost) + { + GhostAdapter.ApplyPostTransformMatrixScale(scale); + } + } #endif /// /// Gets the NetworkManager that owns this NetworkObject instance @@ -2856,33 +2885,53 @@ internal bool InitializeChildNetworkBehaviours() #endif } #if UNIFIED_NETCODE - // For now, cycle through all known NetworkTransform and NetworkRigidbodyBase derived components + // For now, cycle through all known NetworkRigidbodyBase derived components // and destroy them all if this is a hybrid prefab instance. // This allows a user to not have to make direct adjustments until trying out their NGO prefab - // as a hybrid spawned prefab (optional to completely remove, will eventually become obsolete and - // automatically removed later). + // as a hybrid spawned prefab. if (HasGhost && !NetworkManager.DistributedAuthorityMode) { +#if COM_UNITY_MODULES_PHYSICS || COM_UNITY_MODULES_PHYSICS2D + // TODO-UNIFIED: This needs to be updated to make it "opt-in". + // If the GhostAdapter is not configured for prediction but is still using a Rigidbody, then go ahead and remove it on + // the client side to improve performance by default. + // TODO-UNIFIED: Determine if recent unified physics updates does not require checking for prediction. if (NetworkRigidbodies != null) { + var isServer = NetworkManager.IsServer; for (int i = NetworkRigidbodies.Count - 1; i >= 0; i--) { - // TODO-UNIFIED: This needs to be updated to make it "opt-in". - // Only clients remove the rigidbody for performance purposes when running a hybrid spawn client-server topology. - if (!NetworkManager.IsServer) + var currenObject = NetworkRigidbodies[i].gameObject; + var currentHasGhostRigidBody = currenObject.GetComponent() != null; + if (!isServer) { - var rigidBody = NetworkRigidbodies[i].gameObject.GetComponent(); - if (rigidBody != null) +#if COM_UNITY_MODULES_PHYSICS + var rigidBody = currenObject.GetComponent(); + + if (rigidBody != null && !currentHasGhostRigidBody) { Destroy(rigidBody); } +#endif +#if COM_UNITY_MODULES_PHYSICS2D + var rigidBody2D = currenObject.GetComponent(); + if (rigidBody2D != null && !currentHasGhostRigidBody) + { + Destroy(rigidBody2D); + } +#endif } - ChildNetworkBehaviours.Remove(NetworkRigidbodies[i].NetworkBehaviourId); - Destroy(NetworkRigidbodies[i]); + // Both the server and clients will still remove and destroy the NetworkRigidbody + // since there is no point in synchronizing these when it is handled via unified. + var networkRigidbody = NetworkRigidbodies[i]; + NetworkRigidbodies.Remove(networkRigidbody); + ChildNetworkBehaviours.Remove(networkRigidbody.NetworkBehaviourId); + Destroy(networkRigidbody); } - NetworkRigidbodies.Clear(); } - +#endif + // This is defined out since users might have derived NetworkTransforms +#if UNIFIED_NETCODE_DESTROY // When hybrid spawning, the transform is synchronized by the GhostObject. // As a convenience, we remove and destroy all NetworkTransforms. // TODO-Parenting-Related-Area: We need to replicate this functionality in a GhostAdapter @@ -2898,6 +2947,7 @@ internal bool InitializeChildNetworkBehaviours() } NetworkTransforms.Clear(); } +#endif } #endif return true; diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs index 34cf77d959..735fa613b7 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs @@ -421,19 +421,6 @@ public void AddNetworkPrefab(GameObject prefab) { m_NetworkManager.DeferredMessageManager.ProcessTriggers(IDeferredNetworkMessageManager.TriggerType.OnAddPrefab, networkObject.GlobalObjectIdHash); } - -#if UNIFIED_NETCODE - if (m_NetworkManager.IsListening) - { - var ghost = prefab.GetComponent(); - if (ghost) - { - m_NetworkManager.InitializeNetcodeWorld(); - NetCode.Netcode.RegisterPrefabSingleWorld(prefab, m_NetworkManager.IsHost, - m_NetworkManager.NetcodeWorld); - } - } -#endif } /// diff --git a/testproject/Packages/manifest.json b/testproject/Packages/manifest.json index 7b76e49c59..977d751b2c 100644 --- a/testproject/Packages/manifest.json +++ b/testproject/Packages/manifest.json @@ -2,16 +2,16 @@ "disableProjectUpdate": false, "dependencies": { "com.unity.addressables": "2.9.1", - "com.unity.ai.navigation": "2.0.12", + "com.unity.ai.navigation": "2.0.14", "com.unity.collab-proxy": "2.12.4", "com.unity.ide.rider": "3.0.40", "com.unity.ide.visualstudio": "2.0.26", "com.unity.mathematics": "1.3.3", - "com.unity.multiplayer.tools": "2.2.8", + "com.unity.multiplayer.tools": "2.2.9", "com.unity.netcode.gameobjects": "file:../../com.unity.netcode.gameobjects", "com.unity.package-validation-suite": "0.49.0-preview", - "com.unity.services.authentication": "3.6.1", - "com.unity.services.multiplayer": "2.1.3", + "com.unity.services.authentication": "3.7.3", + "com.unity.services.multiplayer": "2.2.4", "com.unity.test-framework": "1.6.0", "com.unity.test-framework.performance": "3.5.0", "com.unity.timeline": "1.8.12", diff --git a/testproject/ProjectSettings/ProjectVersion.txt b/testproject/ProjectSettings/ProjectVersion.txt index 33390a1c17..bed7306bac 100644 --- a/testproject/ProjectSettings/ProjectVersion.txt +++ b/testproject/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 6000.3.17f1 -m_EditorVersionWithRevision: 6000.3.17f1 (cf0352b38e81) +m_EditorVersion: 6000.3.21f1 +m_EditorVersionWithRevision: 6000.3.21f1 (c02631ffc030)