diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs index 103da29d6a..8cb0f48a8f 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/NetworkObjectBridge.cs @@ -2,10 +2,12 @@ using System; using Unity.Entities; using Unity.NetCode; +using UnityEngine; namespace Unity.Netcode { +#if UNIFIED_NETCODE /// /// TODO-UNIFIED: Needs further peer review and exploring alternate ways of handling this. /// @@ -15,7 +17,7 @@ namespace Unity.Netcode public partial class NetworkObjectBridge : GhostBehaviour { -#if UNITY_EDITOR +#if UNITY_EDITOR && !UNITY_INCLUDE_TESTS [UnityEngine.HideInInspector] [UnityEngine.SerializeField] private bool m_Sorted = false; @@ -46,12 +48,13 @@ private void OnValidate() /// N4E-spawned hybrid prefab instances. /// internal GhostField NetworkObjectId = new GhostField(); - - public void SetNetworkObjectId(ulong value) + public void SetNetworkObjectId(ulong networkObjectId) { - NetworkObjectId.Value = value; + NetworkObjectId.PresetValue(networkObjectId); + NetworkObjectId.Value = networkObjectId; } } +#endif /// /// TODO-UNIFIED: Would need to be reviewed for alternate ways of handling this. @@ -63,46 +66,67 @@ internal class UnifiedBootStrap : ClientServerBootstrap public static UnifiedBootStrap Instance { get; private set; } public static Action OnInitialized; public static ushort Port = 7979; + public static NetworkManager CurrentNetworkManagerForInitialization; - public static World World { get; private set; } + public static World LastCreatedWorld { get; private set; } + private static int s_WorldCounter = 0; + public override bool Initialize(string defaultWorldName) { - var networkManager = NetworkManager.Singleton; - Instance = this; + var networkManager = CurrentNetworkManagerForInitialization; + if (networkManager == NetworkManager.Singleton) + { + Instance = this; + } + AutoConnectPort = Port; if (base.Initialize(defaultWorldName)) { - UnityEngine.Debug.LogError($"[{nameof(UnifiedBootStrap)}] Auto-bootstrap is enabled!!! This will break the POC!"); + Debug.LogError($"[{nameof(UnifiedBootStrap)}] Auto-bootstrap is enabled!!! This will break the POC!"); return true; } - World = networkManager.IsServer ? CreateSingleWorldHost("ClientAndServerWorld") : CreateClientWorld("ClientWorld"); - - if (World == null) + if (networkManager != null) { - UnityEngine.Debug.LogError($"[{nameof(UnifiedBootStrap)}] World is null!"); - return false; - } + Debug.Log($"Starting a world for {(networkManager.IsServer ? "Host" : "Client")}"); + s_WorldCounter++; + LastCreatedWorld = networkManager.IsServer ? CreateSingleWorldHost($"HostSingleWorld-{s_WorldCounter}") + : CreateClientWorld($"ClientWorld-{s_WorldCounter}"); - if (!World.IsCreated) - { - UnityEngine.Debug.LogError($"[{nameof(UnifiedBootStrap)}] World was not created!"); - return false; - } + if (LastCreatedWorld == null) + { + s_WorldCounter--; + Debug.LogError($"[{nameof(UnifiedBootStrap)}] World is null!"); + return false; + } - if (networkManager.LogLevel <= LogLevel.Developer) - { - NetworkLog.LogInfo($"[{nameof(UnifiedBootStrap)}] Created world: {World.Name}"); - } + if (!LastCreatedWorld.IsCreated) + { + s_WorldCounter--; + Debug.LogError($"[{nameof(UnifiedBootStrap)}] World was not created!"); + return false; + } - if (networkManager.NetworkConfig.Prefabs.HasPendingGhostPrefabs) - { - if (networkManager.LogLevel <= LogLevel.Developer) + //if (networkManager.LogLevel <= LogLevel.Developer) { - NetworkLog.LogInfo($"[{nameof(UnifiedBootStrap)}] Registering hybrid prefabs..."); + NetworkLog.LogInfo($"[{nameof(UnifiedBootStrap)}] Created world: {LastCreatedWorld.Name} / {LastCreatedWorld.SequenceNumber}"); } - networkManager.NetworkConfig.Prefabs.RegisterGhostPrefabs(networkManager); + + networkManager.NetcodeWorld = (NetcodeWorld)LastCreatedWorld; + if (networkManager.NetworkConfig.Prefabs.HasPendingGhostPrefabs) + { + if (networkManager.LogLevel <= LogLevel.Developer) + { + NetworkLog.LogInfo($"[{nameof(UnifiedBootStrap)}] Registering hybrid prefabs..."); + } + + networkManager.NetworkConfig.Prefabs.RegisterGhostPrefabs(networkManager); + } + } + else + { + LastCreatedWorld = CreateLocalWorld("LocalWorld"); } OnInitialized?.Invoke(); @@ -112,7 +136,7 @@ public override bool Initialize(string defaultWorldName) ~UnifiedBootStrap() { - World = null; + LastCreatedWorld = null; Instance = null; } } diff --git a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs index faa1b12d67..b7730b49cd 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/Helpers/UnifiedUpdateConnections.cs @@ -3,6 +3,7 @@ using Unity.Collections; using Unity.Entities; using Unity.NetCode; +using UnityEngine; namespace Unity.Netcode.Components { @@ -36,64 +37,75 @@ protected override void OnUpdate() { var isServer = World.IsServer(); var commandBuffer = new EntityCommandBuffer(Allocator.Temp); - var networkManager = NetworkManager.Singleton; - - foreach (var (networkId, connectionState, entity) in SystemAPI.Query().WithNone().WithEntityAccess()) - { - commandBuffer.RemoveComponent(entity); - m_TempConnections.Add(new NetcodeConnection { World = World, Entity = entity, NetworkId = networkId.Value }); - } - foreach (var con in m_TempConnections) +// var networkManager = NetworkManager.Singleton; + foreach (var networkManager in GameObject.FindObjectsByType()) { - NetworkManager.OnNetCodeDisconnect?.Invoke(con); - } - - m_TempConnections.Clear(); + foreach (var (networkId, connectionState, entity) in SystemAPI.Query() + .WithNone().WithEntityAccess()) + { + commandBuffer.RemoveComponent(entity); + m_TempConnections.Add(new NetcodeConnection + { World = World, Entity = entity, NetworkId = networkId.Value }); + } - // TODO: We should figure out how to associate the N4E NetworkId with the NGO ClientId - foreach (var (networkId, entity) in SystemAPI.Query().WithAll().WithNone().WithEntityAccess()) - { - if (!m_NewConnections.ContainsKey(networkId.Value)) + foreach (var con in m_TempConnections) { - var newConnection = new NetcodeConnection { World = World, Entity = entity, NetworkId = networkId.Value }; - m_NewConnections.Add(networkId.Value, newConnection); + NetworkManager.OnNetCodeDisconnect?.Invoke(con); } - } - // If we have any pending connections - if (m_NewConnections.Count > 0) - { - foreach (var entry in m_NewConnections) + m_TempConnections.Clear(); + + // TODO: We should figure out how to associate the N4E NetworkId with the NGO ClientId + foreach (var (networkId, entity) in SystemAPI.Query().WithAll() + .WithNone().WithEntityAccess()) { - // Server: always connect - // Client: wait until we have synchronized before announcing we are ready to receive snapshots - if (networkManager.IsServer || (!networkManager.IsServer && networkManager.IsConnectedClient)) + if (!m_NewConnections.ContainsKey(networkId.Value)) { - // Set the connection in-game - commandBuffer.AddComponent(entry.Value.Entity); - commandBuffer.AddComponent(entry.Value.Entity, default(ConnectionState)); - NetworkManager.OnNetCodeConnect?.Invoke(entry.Value); - m_TempConnections.Add(entry.Value); + var newConnection = new NetcodeConnection + { World = World, Entity = entity, NetworkId = networkId.Value }; + m_NewConnections.Add(networkId.Value, newConnection); } } - // Remove any connections that have "gone in-game". - foreach (var connection in m_TempConnections) + + // If we have any pending connections + if (m_NewConnections.Count > 0) { - m_NewConnections.Remove(connection.NetworkId); + foreach (var entry in m_NewConnections) + { + // Server: always connect + // Client: wait until we have synchronized before announcing we are ready to receive snapshots + if (networkManager.IsServer || (!networkManager.IsServer && networkManager.IsConnectedClient)) + { + // Set the connection in-game + commandBuffer.AddComponent(entry.Value.Entity); + commandBuffer.AddComponent(entry.Value.Entity, default(ConnectionState)); + NetworkManager.OnNetCodeConnect?.Invoke(entry.Value); + m_TempConnections.Add(entry.Value); + } + } + + // Remove any connections that have "gone in-game". + foreach (var connection in m_TempConnections) + { + m_NewConnections.Remove(connection.NetworkId); + } } - } - m_TempConnections.Clear(); - // If the local NetworkManager is shutting down or no longer connected, then - // make sure we have disconnected all known connections. - if (networkManager.ShutdownInProgress || !networkManager.IsListening) - { - foreach (var (networkId, entity) in SystemAPI.Query().WithEntityAccess()) + m_TempConnections.Clear(); + + // If the local NetworkManager is shutting down or no longer connected, then + // make sure we have disconnected all known connections. + if (networkManager.ShutdownInProgress || !networkManager.IsListening) { - commandBuffer.RemoveComponent(entity); - NetworkManager.OnNetCodeDisconnect?.Invoke(new NetcodeConnection { World = World, Entity = entity, NetworkId = networkId.Value }); + foreach (var (networkId, entity) in SystemAPI.Query().WithEntityAccess()) + { + commandBuffer.RemoveComponent(entity); + NetworkManager.OnNetCodeDisconnect?.Invoke(new NetcodeConnection + { World = World, Entity = entity, NetworkId = networkId.Value }); + } } } + commandBuffer.Playback(EntityManager); } diff --git a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs index 8474b3b415..e74d2e20d1 100644 --- a/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Runtime/Components/NetworkTransform.cs @@ -3741,7 +3741,7 @@ private void ResetInterpolatedStateToCurrentAuthoritativeState() /// The internal initialzation method to allow for internal API adjustments /// /// - private void InternalInitialization(bool isOwnershipChange = false) + internal virtual void InternalInitialization(bool isOwnershipChange = false) { #if UNIFIED_NETCODE diff --git a/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs b/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs index f414283c0d..c402adf04c 100644 --- a/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs +++ b/com.unity.netcode.gameobjects/Runtime/Configuration/NetworkPrefabs.cs @@ -362,7 +362,7 @@ internal void RegisterGhostPrefabs(NetworkManager networkManager) var networkPrefab = m_PendingGhostRegistration[i]; // Returns false if the single world is not available yet - if (NetCode.Netcode.RegisterPrefabSingleWorld(networkPrefab.Prefab, isHost)) + 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); @@ -394,9 +394,9 @@ private bool AddPrefabRegistration(NetworkPrefab networkPrefab) #if UNIFIED_NETCODE if (networkPrefab.HasGhost) { - HasPendingGhostPrefabs = true; + //HasPendingGhostPrefabs = true; HasGhostPrefabs = true; - m_PendingGhostRegistration.Add(networkPrefab); + //m_PendingGhostRegistration.Add(networkPrefab); } #endif diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs index 9715756023..aa335b53db 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs @@ -1320,57 +1320,31 @@ private bool CanStart(StartType type) return true; } + public NetcodeWorld NetcodeWorld { get; internal set; } + #if UNIFIED_NETCODE - private System.Collections.IEnumerator WaitForHybridPrefabRegistration(StartType startType) + internal void InitializeNetcodeWorld() { - if (NetCode.Netcode.IsActive) + if (NetcodeWorld != null) { - NetworkLog.LogInfo($"[{nameof(WaitForHybridPrefabRegistration)}] Netcode is not active but has an instance at this point."); + return; } - - /// !! Important !! - /// Clear out any pre-existing configuration in the event this applicatioin instance has already been connected to a session. - NetCode.Netcode.Reset(); - - /// !! Initialize worlds here !! - /// Worlds are created here: - DefaultWorldInitialization.Initialize("Default World", false); - - // This should not be needed at this point, but this is here in the event something changes. - if (NetworkConfig.Prefabs.HasPendingGhostPrefabs) + + if (this == Singleton) { - NetworkLog.LogWarning($"[{nameof(WaitForHybridPrefabRegistration)}] !!!!! (Ghosts are still pending registration) !!!!!"); - var waitTime = new WaitForSeconds(0.016f); - while (NetworkConfig.Prefabs.HasPendingGhostPrefabs) + if (NetCode.Netcode.IsActive) { - NetworkConfig.Prefabs.RegisterGhostPrefabs(this); - yield return waitTime; + NetworkLog.LogInfo($"[{nameof(InitializeNetcodeWorld)}] 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(); } - if (LogLevel <= LogLevel.Developer) - { - NetworkLog.LogInfo($"[{nameof(WaitForHybridPrefabRegistration)}] All hybrid prefabs have been registered!"); - NetworkLog.LogInfo($"[{nameof(WaitForHybridPrefabRegistration)}] Finalizing NetworkManager start..."); - } - switch (startType) - { - case StartType.Server: - { - InternalStartServer(); - break; - } - case StartType.Host: - { - InternalStartHost(); - break; - } - case StartType.Client: - { - InternalStartClient(); - break; - } - } + /// !! Initialize worlds here !! + /// Worlds are created here: + UnifiedBootStrap.CurrentNetworkManagerForInitialization = this; + DefaultWorldInitialization.Initialize("Default World", false); } private bool UnifiedIsConfiguredCorrectly() @@ -1438,8 +1412,8 @@ public bool StartServer() { Debug.Log("Creating world: Default world"); } - StartCoroutine(WaitForHybridPrefabRegistration(StartType.Server)); - return true; + InitializeNetcodeWorld(); + return InternalStartServer(); } else { @@ -1525,9 +1499,8 @@ public bool StartClient() { Debug.Log("Creating world: Default world"); } - StartCoroutine(WaitForHybridPrefabRegistration(StartType.Client)); - // TODO-UNIFIED: Need a way to signal everything completed. - return true; + InitializeNetcodeWorld(); + return InternalStartClient(); } else { @@ -1612,9 +1585,8 @@ public bool StartHost() { Debug.Log("Creating world: Default world"); } - StartCoroutine(WaitForHybridPrefabRegistration(StartType.Host)); - // TODO-UNIFIED: Need a way to signal everything completed. - return true; + InitializeNetcodeWorld(); + return InternalStartHost(); } else { diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs index 43de83f0ce..3992345b99 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs @@ -2005,6 +2005,12 @@ public void SpawnAsPlayerObject(ulong clientId, bool destroyWithScene = false) /// (true) the will be destroyed (false) the will persist after being despawned public void Despawn(bool destroy = true) { +#if UNIFIED_NETCODE + if (HasGhost && destroy == false) + { + throw new NotSupportedException("Despawn without destroy is not supported for hybrid objects."); + } +#endif if (!IsSpawned) { if (NetworkManager.LogLevel <= LogLevel.Error) @@ -3852,9 +3858,13 @@ private void OnEnable() private void OnDisable() { Debug.Log("Disabled!"); - if (IsSpawned) + if (IsSpawned || HasGhost) { - enabled = true; + if (HasGhost && GhostAdapter.IsPrefab()) + { + return; + } + gameObject.SetActive(true); } try @@ -3870,13 +3880,6 @@ private void OnDisable() private void Start() { - // TODO-UNIFIED: Remove once the prefab registration is in place. - if (!enabled) - { - Debug.LogWarning($"[{nameof(NetworkObject)}][{name}] Was not enabled on start! Enabling."); - enabled = true; - } - InitGhost(); } [SerializeField] @@ -3886,13 +3889,13 @@ private void Start() private void InitGhost() { // All instances with Ghosts are automatically registered - if (HasGhost && NetworkObjectBridge) + if (HasGhost && NetworkObjectBridge && !GhostAdapter.IsPrefab()) { if (NetworkManager.LogLevel == LogLevel.Developer) { Debug.Log($"[{nameof(NetworkObject)}] GhostBridge {name} detected and instantiated."); } - if (NetworkObjectBridge.NetworkObjectId.Value != 0) + if (GhostAdapter.WasInitialized && NetworkObjectBridge.NetworkObjectId.Value != 0) { RegisterGhostBridge(); } @@ -3904,9 +3907,23 @@ internal void RegisterGhostBridge() if (NetworkManager.LogLevel == LogLevel.Developer) { Debug.Log($"[{nameof(NetworkObject)}][{nameof(NetworkObjectId)}] NetworkObjectBridge notified instance exists with assigned ID of: {NetworkObjectBridge.NetworkObjectId.Value}"); + if (!NetworkManager.IsListening) + { + Debug.LogWarning($"[{nameof(NetworkObject)}] Did not register because there is no session in progress!"); + return; + } } - if (!NetworkManager.IsServer) + // Set when running through integration tests in order to initially bypass the + // normal registration. This is because at this point in the instantiation process, + // NetworkObject's NetworkManager is pointing to the singleton which means all instances + // (even if intended to be for a specific client) will end up registering with whichever + // NetworkManager instance is being pointed to by the singleton. + if (NetworkSpawnManager.RegisterPendingGhost != null) + { + NetworkSpawnManager.RegisterPendingGhost(this, NetworkObjectBridge.NetworkObjectId.Value); + } + else if (!NetworkManager.IsServer) { NetworkManager.SpawnManager.RegisterGhostPendingSpawn(this, NetworkObjectBridge.NetworkObjectId.Value); } diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/DeferredMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/DeferredMessageManager.cs index f05d000fec..c68173e60d 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/DeferredMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/DeferredMessageManager.cs @@ -125,6 +125,16 @@ protected virtual void PurgeTrigger(IDeferredNetworkMessageManager.TriggerType t triggerInfo.TriggerData.Dispose(); } + public bool HasAnyOfTrigger(IDeferredNetworkMessageManager.TriggerType trigger) + { + if (m_Triggers.TryGetValue(trigger, out var triggers)) + { + return triggers.Count != 0; + } + + return false; + } + public virtual void ProcessTriggers(IDeferredNetworkMessageManager.TriggerType trigger, ulong key) { if (m_Triggers.TryGetValue(trigger, out var triggers)) @@ -143,6 +153,11 @@ public virtual void ProcessTriggers(IDeferredNetworkMessageManager.TriggerType t triggerInfo.TriggerData.Dispose(); } } + + if (trigger != IDeferredNetworkMessageManager.TriggerType.OnOtherTriggerFinishedProcessing) + { + ProcessTriggers(IDeferredNetworkMessageManager.TriggerType.OnOtherTriggerFinishedProcessing, (ulong)trigger); + } } /// diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/IDeferredNetworkMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/IDeferredNetworkMessageManager.cs index 2e6dd7cfbd..64ad123166 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/IDeferredNetworkMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/IDeferredNetworkMessageManager.cs @@ -11,6 +11,7 @@ internal enum TriggerType #if UNIFIED_NETCODE OnGhostSpawned, #endif + OnOtherTriggerFinishedProcessing, } /// @@ -31,6 +32,8 @@ internal enum TriggerType public void ProcessTriggers(TriggerType trigger, ulong key); + public bool HasAnyOfTrigger(IDeferredNetworkMessageManager.TriggerType trigger); + /// /// Cleans up any trigger that's existed for more than a second. /// These triggers were probably for situations where a request was received after a despawn rather than before a spawn. diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/CreateObjectMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/CreateObjectMessage.cs index ac1c07efc0..4812c3680d 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/CreateObjectMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/CreateObjectMessage.cs @@ -131,7 +131,7 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int { if (networkManager.LogLevel == LogLevel.Developer) { - UnityEngine.Debug.Log($"Deferring {nameof(CreateObjectMessage)} to wait for Ghost."); + UnityEngine.Debug.Log($"[{nameof(NetworkObject)}-{ObjectInfo.NetworkObjectId}] Deferring {nameof(CreateObjectMessage)} to wait for Ghost."); } networkManager.DeferredMessageManager.DeferMessage(IDeferredNetworkMessageManager.TriggerType.OnGhostSpawned, ObjectInfo.NetworkObjectId, reader, ref context, k_Name); return false; diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/SceneEventMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/SceneEventMessage.cs index c0452146b4..4a3376d912 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/SceneEventMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/SceneEventMessage.cs @@ -8,6 +8,7 @@ internal struct SceneEventMessage : INetworkMessage public SceneEventData EventData; + private const string k_Name = "SceneEventMessage"; private FastBufferReader m_ReceivedData; @@ -18,6 +19,15 @@ public void Serialize(FastBufferWriter writer, int targetVersion) public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int receivedMessageVersion) { + var networkManager = (NetworkManager)context.SystemOwner; +#if UNIFIED_NETCODE + if (networkManager.DeferredMessageManager.HasAnyOfTrigger(IDeferredNetworkMessageManager.TriggerType + .OnGhostSpawned)) + { + networkManager.DeferredMessageManager.DeferMessage(IDeferredNetworkMessageManager.TriggerType.OnOtherTriggerFinishedProcessing, (ulong)IDeferredNetworkMessageManager.TriggerType.OnGhostSpawned, reader, ref context, k_Name); + return false; + } +#endif m_ReceivedData = reader; return true; } diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs index c8aab939f4..11a5a0be65 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Generic; +#if UNIFIED_NETCODE +using Unity.NetCode; +#endif using UnityEngine; namespace Unity.Netcode @@ -418,6 +421,19 @@ 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/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs index df40f2cdac..de8bc86192 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs @@ -35,6 +35,13 @@ public class NetworkSpawnManager internal readonly Dictionary GhostsPendingSpawn = new Dictionary(); + // TODO: We might want to make this a mock interfacebut temporary solution to validate + // the need to assure we are registering with the right NetworkManager instance when testing (everything + // will use the singleton during Awake and Start when we need to register). + internal delegate void RegisterPendingGhostDelegateHandler(NetworkObject networkObject, ulong networkObjectId); + + internal static RegisterPendingGhostDelegateHandler RegisterPendingGhost; + internal void RegisterGhostPendingSpawn(NetworkObject networkObject, ulong networkObjectId) { if (NetworkManager.LogLevel == LogLevel.Developer) @@ -43,6 +50,7 @@ internal void RegisterGhostPendingSpawn(NetworkObject networkObject, ulong netwo } if (GhostsPendingSpawn.TryAdd(networkObjectId, networkObject)) { + // TODO-REVIEW-BELOW: *** This is very likely no longer an issue with the new connection sequence *** // TODO-UNIFIED: We need a better way to preserve any hybrid instances pending NGO spawn. // Edge-Case scenario: During initial client synchronization (i.e. !NetworkManager.IsConnectedClient). // diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs index eadfd1db26..96f59045a5 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/Unified/UnifiedNetcodeTransport.cs @@ -248,7 +248,7 @@ public override unsafe void Send(ulong clientId, ArraySegment payload, Net var amount = connectionInfo.SendQueue.FillWriterWithBytes(ref writer, k_MaxPacketSize); rpc.Value.Buffer.Length = amount; - var updateSystem = NetCode.Netcode.GetWorld(false).GetExistingSystemManaged(); + var updateSystem = m_NetworkManager.NetcodeWorld.GetExistingSystemManaged(); updateSystem.SendRpc(rpc); connectionInfo.SendQueue.Consume(amount); @@ -368,12 +368,37 @@ private void OnServerClientDisconnected(Connection connection, NetCodeConnection { InvokeOnTransportEvent(NetworkEvent.Disconnect, (ulong)connection.NetworkId.Value, default, m_RealTimeProvider.RealTimeSinceStartup); } + + private void OnClientConnectionEvent(Connection connection, NetCodeConnectionEvent connectionEvent) + { + switch (connectionEvent.State) + { + case ConnectionState.State.Connected: + OnClientConnectedToServer(connection, connectionEvent); + break; + case ConnectionState.State.Disconnected: + OnClientDisconnectFromServer(connection, connectionEvent); + break; + } + } + + private void OnServerConnectionEvent(Connection connection, NetCodeConnectionEvent connectionEvent) + { + switch (connectionEvent.State) + { + case ConnectionState.State.Connected: + OnServerNewClientConnection(connection, connectionEvent); + break; + case ConnectionState.State.Disconnected: + OnServerClientDisconnected(connection, connectionEvent); + break; + } + } public override bool StartClient() { - NetCode.Netcode.Client.OnConnect = OnClientConnectedToServer; - NetCode.Netcode.Client.OnDisconnect = OnClientDisconnectFromServer; - var updateSystem = NetCode.Netcode.GetWorld(false).GetExistingSystemManaged(); + m_NetworkManager.NetcodeWorld.OnConnectionEvent += OnClientConnectionEvent; + var updateSystem = m_NetworkManager.NetcodeWorld.GetExistingSystemManaged(); updateSystem.Transport = this; updateSystem.NetworkManager = m_NetworkManager; return true; @@ -381,14 +406,13 @@ public override bool StartClient() public override bool StartServer() { - foreach (var connection in NetCode.Netcode.Server.Connections) + foreach (var connection in m_NetworkManager.NetcodeWorld.AllConnections) { OnServerNewClientConnection(connection, default); } - NetCode.Netcode.Server.OnConnect = OnServerNewClientConnection; - NetCode.Netcode.Server.OnDisconnect = OnServerClientDisconnected; - var updateSystem = NetCode.Netcode.GetWorld(true).GetExistingSystemManaged(); + m_NetworkManager.NetcodeWorld.OnConnectionEvent += OnServerConnectionEvent; + var updateSystem = m_NetworkManager.NetcodeWorld.GetExistingSystemManaged(); updateSystem.Transport = this; updateSystem.NetworkManager = m_NetworkManager; return true; @@ -396,16 +420,35 @@ public override bool StartServer() public override void DisconnectRemoteClient(ulong clientId) { - var updateSystem = NetCode.Netcode.GetWorld(true).GetExistingSystemManaged(); - updateSystem.Disconnect(m_Connections[(int)clientId].Connection); + m_NetworkManager.NetcodeWorld.DisconnectAClient(m_Connections[(int)clientId].Connection); m_Connections.Remove((int)clientId); } public override void DisconnectLocalClient() { - var updateSystem = NetCode.Netcode.GetWorld(false).GetExistingSystemManaged(); - updateSystem.Disconnect(m_Connections[(int)ServerClientId].Connection); + // Remove the connection 1st (the world might not be available) m_Connections.Remove((int)ServerClientId); + + // TODO-FIX-REVIEW-ME: + // This was causing errors to occur upon shutdown during an integration test. + // The cases being trapped for below yield no errors, but there might be some + // form of other underlying issue here: + + if (m_NetworkManager.NetcodeWorld == null || !m_NetworkManager.NetcodeWorld.IsCreated) + { + return; + } + + if (m_NetworkManager.IsServer || m_NetworkManager.NetcodeWorld.IsHost()) + { + if (m_NetworkManager.LogLevel <= LogLevel.Developer) + { + Debug.LogWarning("Host is attempting to shutdown the local client which is not required with a single world host."); + } + return; + } + m_NetworkManager.NetcodeWorld.RequestDisconnectFromServer(); + } public override ulong GetCurrentRtt(ulong clientId) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/UnifiedNetworkTransformTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/UnifiedNetworkTransformTest.cs new file mode 100644 index 0000000000..ef09d0829a --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/UnifiedNetworkTransformTest.cs @@ -0,0 +1,108 @@ +using System.Collections; +using NUnit.Framework; +using Unity.Netcode.Components; +using Unity.Netcode.TestHelpers.Runtime; +using Unity.NetCode; +using UnityEngine; +using UnityEngine.TestTools; + + +namespace Unity.Netcode.RuntimeTests +{ + /// + /// Test class that deliberately removes some functionality from NetworkTransform that is conditionally disabled + /// by the presence of ghost objects in the base class. This is to help be certain that the network transform + /// is not doing the work, but that the work is being done by N4E's snapshots. + /// + internal class DoNothingNetworkTransform : NetworkTransform + { + public override void OnNetworkSpawn() + { + // Deliberately left empty + } + + internal override void InternalInitialization(bool isOwnershipChange = false) + { + // Deliberately left empty + } + } + + internal class UnifiedNetworkTransformTest : IntegrationTestWithApproximation + { + protected override int NumberOfClients => 2; + + private GameObject m_Prefab; + private NetworkObject m_Instance; + + protected override IEnumerator OnSetup() + { + // Creates the hybrid prefab + m_Prefab = CreateHybridPrefab("HybridPrefab", true); + m_Prefab.AddComponent(); + return base.OnSetup(); + } + + protected override void OnServerAndClientsCreated() + { + + // Add the hybrid prefab to the prefabs list for + // all NetworkManager instances. + // TODO: Emma and I discussed actually not making it + // a requirement to have NetworkManager instances. + // We can get that PR landed and merged back into the + // unified branch so this is no longer needed. + // (We can modify CreateHybridPrefab to use whatever list + // is used to handle this when using the normal prefab creation + // methods). + var networkPrefab = new NetworkPrefab() + { + Prefab = m_Prefab, + }; + foreach (var networkManager in m_NetworkManagers) + { + networkManager.LogLevel = LogLevel.Developer; + networkManager.NetworkConfig.Prefabs.Add(networkPrefab); + // Set the deferred message timeout to be 5 seconds for this test. + // (To see if the messages for the instances ever get processed.) + // Enable this to debug deferred + //networkManager.NetworkConfig.SpawnTimeout = 5; + } + } + + [UnityTest] + public IEnumerator BasicMovementTest() + { + m_EnableVerboseDebug = true; + var authority = GetAuthorityNetworkManager(); + m_Instance = SpawnObject(m_Prefab, m_ServerNetworkManager).GetComponent(); + + // Wait 5 seconds so we will dump any deferred messages if it failed on clients + // when checking to see if it spawned or not on the clients next. + // Enable this to debug deferred + //yield return new WaitForSeconds(5); + + yield return WaitForSpawnedOnAllOrTimeOut(m_Instance); + AssertOnTimeout($"Failed to spawn {m_Instance.name} on all clients!"); + + VerboseDebug("All clients spawned instance!"); + + var originalPos = authority.LocalClient.PlayerObject.transform.position; + var newPos = originalPos + new Vector3(1, 1, 1); + + m_Instance.transform.position = newPos; + + foreach (var client in m_ClientNetworkManagers) + { + Assert.IsTrue(Approximately(originalPos, s_GlobalNetworkObjects[client.LocalClientId][m_Instance.NetworkObjectId].transform.position)); + } + + yield return new WaitForSeconds(1); + + foreach (var client in m_ClientNetworkManagers) + { + Assert.IsTrue(Approximately(newPos, s_GlobalNetworkObjects[client.LocalClientId][m_Instance.NetworkObjectId].transform.position)); + } + VerboseDebug("Test Passed!"); + } + } +} diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/UnifiedNetworkTransformTest.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/UnifiedNetworkTransformTest.cs.meta new file mode 100644 index 0000000000..10d990cfa3 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/UnifiedNetworkTransformTest.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0f26fa7bd5474b3f9947e0813374b50f +timeCreated: 1775078549 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs index 9e439ba098..0bd0522662 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTest.cs @@ -6,6 +6,7 @@ using System.Runtime.CompilerServices; using System.Text; using NUnit.Framework; +using Unity.NetCode; using Unity.Netcode.RuntimeTests; using Unity.Netcode.Transports.UTP; using UnityEngine; @@ -223,7 +224,17 @@ public enum HostOrServer /// /// Denotes that distributed authority is being used. /// - DAHost + DAHost, +#if UNIFIED_NETCODE + /// + /// Use N4E-backed hybrid spawning in server mode + /// + UnifiedServer, + /// + /// Use N4E-backed hybrid spawning in host mode + /// + UnifiedHost +#endif } /// @@ -626,6 +637,10 @@ private void InternalOnOneTimeSetup() /// protected virtual IEnumerator OnSetup() { + if(m_allPrefabsAsHybrid) + { + NetworkSpawnManager.RegisterPendingGhost = RegisterPendingGhost; + } yield return null; } @@ -639,6 +654,10 @@ protected virtual IEnumerator OnSetup() /// protected virtual void OnInlineSetup() { + if(m_allPrefabsAsHybrid) + { + NetworkSpawnManager.RegisterPendingGhost = RegisterPendingGhost; + } } /// @@ -705,6 +724,22 @@ public IEnumerator SetUp() VerboseDebug($"Exiting {nameof(SetUp)}"); } + private void RegisterPendingGhost(NetworkObject networkObject, ulong networkObjectId) + { + var ghost = networkObject.GetComponent(); + Assert.IsNotNull(ghost, $"[RegisterPendingGhost][NetworkObject-{networkObjectId}] Has no {nameof(GhostAdapter)}!"); + foreach (var networkManager in m_NetworkManagers) + { + // If the world matches, then register the instance with this NetworkManager's spawn manager. + if (networkManager.NetcodeWorld == ghost.World) + { + networkManager.SpawnManager.RegisterGhostPendingSpawn(networkObject, networkObjectId); + return; + } + } + Debug.LogError($"Did not find a world for NetworkObject-{networkObjectId}!!"); + } + /// /// Override this to add components or adjustments to the default player prefab /// @@ -1595,6 +1630,17 @@ protected IEnumerator CoroutineShutdownAndCleanUp() DestroyNetworkManagers(); } + protected void UnifiedCleanup() + { +#if UNIFIED_NETCODE + if(m_allPrefabsAsHybrid) + { + NetworkSpawnManager.RegisterPendingGhost = null; + CleanupPrefabReferences(); + } +#endif + } + /// /// Note: For mode /// this is called before ShutdownAndCleanUp. @@ -1602,6 +1648,7 @@ protected IEnumerator CoroutineShutdownAndCleanUp() /// protected virtual IEnumerator OnTearDown() { + UnifiedCleanup(); yield return null; } @@ -1610,6 +1657,7 @@ protected virtual IEnumerator OnTearDown() /// protected virtual void OnInlineTearDown() { + UnifiedCleanup(); } /// @@ -1745,6 +1793,22 @@ protected void DestroySceneNetworkObjects() if (CanDestroyNetworkObject(networkObject)) { + // Handle removing the prefab reference and destroying it + // and then destroying the ghostAdapter prior to destroying + // a hybrid prefab. + var ghostAdapter = networkObject.GetComponent(); + if (ghostAdapter != null && ghostAdapter.prefabReference != null) + { + var prefabReference = ghostAdapter.prefabReference; + prefabReference.Prefab = null; + ghostAdapter.prefabReference = null; + Object.Destroy(prefabReference); + Object.Destroy(ghostAdapter); + // Only normally destroy hybrid-spawned objects. + Object.Destroy(networkObject.gameObject); + continue; + } + // Destroy the GameObject that holds the NetworkObject component Object.DestroyImmediate(networkObject.gameObject); } @@ -2171,6 +2235,10 @@ internal void WaitForMessagesReceivedWithTimeTravel(List messagesInOrder, Assert.True(WaitForConditionOrTimeOutWithTimeTravel(hooks), $"[Messages Not Recieved] {hooks.GetHooksStillWaiting()}"); } +#if UNIFIED_NETCODE + protected bool m_allPrefabsAsHybrid = false; +#endif + /// /// Creates a basic NetworkObject test prefab, assigns it to a new /// NetworkPrefab entry, and then adds it to the server and client(s) @@ -2180,6 +2248,12 @@ internal void WaitForMessagesReceivedWithTimeTravel(List messagesInOrder, /// The assigned to the new NetworkPrefab entry protected GameObject CreateNetworkObjectPrefab(string baseName) { +#if UNIFIED_NETCODE + if (m_allPrefabsAsHybrid) + { + return CreateHybridPrefab(baseName); + } +#endif var prefabCreateAssertError = $"You can only invoke this method during {nameof(OnServerAndClientsCreated)} " + $"but before {nameof(OnStartedServerAndClients)}!"; var authorityNetworkManager = GetAuthorityNetworkManager(); @@ -2192,6 +2266,90 @@ protected GameObject CreateNetworkObjectPrefab(string baseName) return prefabObject; } +#if UNIFIED_NETCODE + protected void CleanupPrefabReferences() + { + foreach (var reference in Object.FindObjectsByType()) + { + Object.Destroy(reference); + } + } + protected GameObject CreateHybridPrefab(string baseName, bool moveToDDOL = true) + { + // Prevent from trying to register/spawn when creating this hybrid prefab + var gameObject = new GameObject + { + name = baseName + }; + + // Order of operations in how these execute is actually important. + // GhostObject should execute 1st. + // NetworkObjectBridge 2nd. + // NetworkObject 3rd. + // NetworkBehaviours will execute in the order they are arranged unless otherwise specified. + + // When adding a Hybrid/Ghost prefab: + // - We disabled the GameObject prior to adding the GhostPrefabReference (so IsPrefab() == true). + // - Add the GhostAdapter and GhostPrefabReference + // - Then set it back to active. + gameObject.SetActive(false); + var adapter = gameObject.AddComponent(); + // Mark the reference as post processing to avoid registering this instance automatically. + GhostPrefabReference.s_IsPostProcessing = true; + adapter.prefabReference = ScriptableObject.CreateInstance(); + adapter.prefabReference.name = "GhostPrefabReference"; + adapter.prefabReference.Prefab = gameObject; + adapter.prefabReference.Ghost = adapter; + GhostPrefabReference.s_IsPostProcessing = false; + + // TODO: This might be part of the CreateHybridPrefab parameters + // For now, just use normal interpolation until we get integration + // tests running. + // Once we have validated prediction works and have a working manual + // test, we can circle back to this (possibly make that a sub-task + // with the dependency to prediction manual test). + adapter.SupportedGhostModes = GhostModeMask.Interpolated; + + // Once done with setting up the GhostAdapter, we can set it back to active in the hierarchy + gameObject.SetActive(true); + + // GhostBehaviours that are part of a prefab will not invoke Ghost.InternalAcquireEntityReference + // Add the bridge + var bridge = gameObject.AddComponent(); + + // Now add NGO components + var no = gameObject.AddComponent(); + + // NetworkObject Ghost specific settings + no.HasGhost = true; + no.GhostAdapter = adapter; + no.HadBridge = true; + no.NetworkObjectBridge = bridge; + + // Disable transform synchronization for NetworkObject serialization + // since that is handled by the GhostAdapter. + no.SynchronizeTransform = false; + + // Turn it into a test prefab + NetcodeIntegrationTestHelpers.MakeNetworkObjectTestPrefab(no); + if (moveToDDOL) + { + Object.DontDestroyOnLoad(gameObject); + } + var authorityNetworkManager = GetAuthorityNetworkManager(); + authorityNetworkManager.AddNetworkPrefab(gameObject); + foreach (var clientNetworkManager in m_ClientNetworkManagers) + { + if (clientNetworkManager == authorityNetworkManager) + { + continue; + } + clientNetworkManager.AddNetworkPrefab(gameObject); + } + return gameObject; + } +#endif + /// /// Overloaded method /// @@ -2294,6 +2452,7 @@ protected void SpawnObjectInstance(NetworkObject networkObjectToSpawn, NetworkMa private GameObject SpawnObject(NetworkObject prefabNetworkObject, NetworkManager owner, bool destroyWithScene = false, bool isPlayerObject = false) { Assert.IsTrue(prefabNetworkObject.GlobalObjectIdHash > 0, $"{nameof(GameObject)} {prefabNetworkObject.name} has a {nameof(NetworkObject.GlobalObjectIdHash)} value of 0! Make sure to make it a valid prefab before trying to spawn!"); + NetCode.Netcode.Instance.m_ActiveWorld = owner.NetcodeWorld; var newInstance = Object.Instantiate(prefabNetworkObject.gameObject); var networkObjectToSpawn = newInstance.GetComponent(); SpawnObjectInstance(networkObjectToSpawn, owner, destroyWithScene, isPlayerObject); @@ -2399,8 +2558,12 @@ private void InitializeTestConfiguration(NetworkTopologyTypes networkTopologyTyp // Note: For m_DistributedAuthority to be true, the m_NetworkTopologyType must be set to NetworkTopologyTypes.DistributedAuthority hostOrServer = m_DistributedAuthority ? HostOrServer.DAHost : HostOrServer.Host; } +#if UNIFIED_NETCODE + m_UseHost = hostOrServer == HostOrServer.Host || hostOrServer == HostOrServer.DAHost || hostOrServer == HostOrServer.UnifiedHost; + m_allPrefabsAsHybrid = (hostOrServer == HostOrServer.UnifiedServer || hostOrServer == HostOrServer.UnifiedHost); +#else m_UseHost = hostOrServer == HostOrServer.Host || hostOrServer == HostOrServer.DAHost; - +#endif // If we are using a distributed authority network topology and the environment variable // to use the CMBService is set, then perform the m_UseCmbService check. if (m_DistributedAuthority && GetServiceEnvironmentVariable()) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTestHelpers.cs b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTestHelpers.cs index 32a0f734d7..6e031c6866 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTestHelpers.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/TestHelpers/NetcodeIntegrationTestHelpers.cs @@ -745,18 +745,17 @@ public static GameObject CreateNetworkObjectPrefab(string baseName, NetworkManag Assert.IsFalse(authorityNetworkManager.IsListening, prefabCreateAssertError); var gameObject = CreateNetworkObject(baseName); - var networkPrefab = new NetworkPrefab() { Prefab = gameObject }; // We could refactor this test framework to share a NetworkPrefabList instance, but at this point it's // probably more trouble than it's worth to verify these lists stay in sync across all tests... - authorityNetworkManager.NetworkConfig.Prefabs.Add(networkPrefab); + authorityNetworkManager.AddNetworkPrefab(gameObject); foreach (var clientNetworkManager in clients) { if (clientNetworkManager == authorityNetworkManager) { continue; } - clientNetworkManager.NetworkConfig.Prefabs.Add(new NetworkPrefab() { Prefab = gameObject }); + clientNetworkManager.AddNetworkPrefab(gameObject); } return gameObject; } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef b/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef index fa718f8b04..86b6bae95f 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Unity.Netcode.Runtime.Tests.asmdef @@ -13,7 +13,9 @@ "Unity.Netcode.TestHelpers.Runtime", "Unity.Mathematics", "UnityEngine.TestRunner", - "UnityEditor.TestRunner" + "UnityEditor.TestRunner", + "Unity.NetCode", + "Unity.Entities" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/testproject/Assets/NetCodeConfig.asset b/testproject/Assets/NetCodeConfig.asset new file mode 100644 index 0000000000..f6b1280970 --- /dev/null +++ b/testproject/Assets/NetCodeConfig.asset @@ -0,0 +1,76 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: abd30ee0214cf6a45b2d76765a4615b1, type: 3} + m_Name: NetCodeConfig + m_EditorClassIdentifier: Unity.NetCode::Unity.NetCode.NetCodeConfig + IsGlobalConfig: 1 + EnableClientServerBootstrap: 0 + HostWorldModeSelection: 1 + ClientServerTickRate: + SimulationTickRate: 30 + PredictedFixedStepSimulationTickRatio: 1 + NetworkTickRate: 0 + MaxSimulationStepsPerFrame: 1 + MaxSimulationStepBatchSize: 4 + TargetFrameRateMode: 0 + m_SendSnapshotsForCatchUpTicks: 0 + SnapshotAckMaskCapacity: 4096 + m_ClampPartialTicksThreshold: 5 + HandshakeApprovalTimeoutMS: 5000 + ClientTickRate: + InterpolationTimeNetTicks: 2 + InterpolationTimeMS: 0 + MaxExtrapolationTimeSimTicks: 20 + ForcedInputLatencyTicks: 0 + MaxPredictAheadTimeMS: 500 + NumAdditionalClientPredictedGhostLifetimeTicks: 0 + DefaultClassificationAllowableTickPeriod: 5 + TargetCommandSlack: 2 + NumAdditionalCommandsToSend: 2 + MaxPredictionStepBatchSizeRepeatedTick: 0 + MaxPredictionStepBatchSizeFirstTimeTick: 0 + PredictionLoopUpdateMode: 0 + InterpolationDelayJitterScale: 1.25 + InterpolationDelayMaxDeltaTicksFraction: 0.1 + InterpolationDelayCorrectionFraction: 0.1 + InterpolationTimeScaleMin: 0.85 + InterpolationTimeScaleMax: 1.1 + CommandAgeCorrectionFraction: 0.1 + PredictionTimeScaleMin: 0.9 + PredictionTimeScaleMax: 1.1 + GhostSendSystemData: + DefaultSnapshotPacketSize: 0 + PercentReservedForDespawnMessages: 0.33 + MinSendImportance: 0 + MinDistanceScaledSendImportance: 0 + MaxIterateChunks: 0 + MaxSendChunks: 0 + MaxSendEntities: 0 + m_ForceSingleBaseline: 0 + m_ForcePreSerialize: 0 + m_KeepSnapshotHistoryOnStructuralChange: 1 + m_EnablePerComponentProfiling: 0 + CleanupConnectionStatePerTick: 1 + m_FirstSendImportanceMultiplier: 1 + m_IrrelevantImportanceDownScale: 1 + m_TempStreamSize: 8192 + m_UseCustomSerializer: 0 + ConnectTimeoutMS: 1000 + MaxConnectAttempts: 60 + DisconnectTimeoutMS: 30000 + HeartbeatTimeoutMS: 500 + ReconnectionTimeoutMS: 2000 + ClientSendQueueCapacity: 64 + ClientReceiveQueueCapacity: 64 + ServerSendQueueCapacity: 512 + ServerReceiveQueueCapacity: 512 + MaxMessageSize: 1400 diff --git a/testproject/Assets/NetCodeConfig.asset.meta b/testproject/Assets/NetCodeConfig.asset.meta new file mode 100644 index 0000000000..222ccfadf4 --- /dev/null +++ b/testproject/Assets/NetCodeConfig.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c547acbddd81d32a0ba5e62ddfc4f4e3 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/testproject/Assets/Tests/Manual/DontDestroyOnLoad/ObjectToNotDestroyBehaviour.cs b/testproject/Assets/Tests/Manual/DontDestroyOnLoad/ObjectToNotDestroyBehaviour.cs index 0ab1566882..488dd63fb6 100644 --- a/testproject/Assets/Tests/Manual/DontDestroyOnLoad/ObjectToNotDestroyBehaviour.cs +++ b/testproject/Assets/Tests/Manual/DontDestroyOnLoad/ObjectToNotDestroyBehaviour.cs @@ -23,7 +23,7 @@ public uint CurrentPing /// /// When enabled, we move ourself to the DontDestroyOnLoad scene /// - private void OnEnable() + protected override void OnNetworkPreSpawn(ref NetworkManager networkManager) { DontDestroyOnLoad(this); } diff --git a/testproject/Assets/Tests/Runtime/AddressablesTests.cs b/testproject/Assets/Tests/Runtime/AddressablesTests.cs index 4c9151c0f3..fb492b9540 100644 --- a/testproject/Assets/Tests/Runtime/AddressablesTests.cs +++ b/testproject/Assets/Tests/Runtime/AddressablesTests.cs @@ -15,6 +15,10 @@ namespace TestProject.RuntimeTests [TestFixture(HostOrServer.DAHost)] [TestFixture(HostOrServer.Host)] [TestFixture(HostOrServer.Server)] +#if UNIFIED_NETCODE + [TestFixture(HostOrServer.UnifiedHost)] + [TestFixture(HostOrServer.UnifiedServer)] +#endif public class AddressablesTests : NetcodeIntegrationTest { protected override int NumberOfClients => 2; diff --git a/testproject/Assets/Tests/Runtime/DontDestroyOnLoadTests.cs b/testproject/Assets/Tests/Runtime/DontDestroyOnLoadTests.cs index 105265b08f..2d841049ca 100644 --- a/testproject/Assets/Tests/Runtime/DontDestroyOnLoadTests.cs +++ b/testproject/Assets/Tests/Runtime/DontDestroyOnLoadTests.cs @@ -11,6 +11,9 @@ namespace TestProject.RuntimeTests { [TestFixture(HostOrServer.Host)] [TestFixture(HostOrServer.DAHost)] +#if UNIFIED_NETCODE + [TestFixture(HostOrServer.UnifiedHost)] +#endif public class DontDestroyOnLoadTests : NetcodeIntegrationTest { private const int k_ClientsToConnect = 4; diff --git a/testproject/Assets/Tests/Runtime/NetworkBehaviourSessionSynchronized.cs b/testproject/Assets/Tests/Runtime/NetworkBehaviourSessionSynchronized.cs index 771a90b9b8..0582211d0f 100644 --- a/testproject/Assets/Tests/Runtime/NetworkBehaviourSessionSynchronized.cs +++ b/testproject/Assets/Tests/Runtime/NetworkBehaviourSessionSynchronized.cs @@ -9,6 +9,9 @@ namespace TestProject.RuntimeTests { [TestFixture(HostOrServer.Host)] [TestFixture(HostOrServer.DAHost)] +#if UNIFIED_NETCODE + [TestFixture(HostOrServer.UnifiedHost)] +#endif public class NetworkBehaviourSessionSynchronized : NetcodeIntegrationTest { private const string k_SceneToLoad = "SessionSynchronize"; diff --git a/testproject/Assets/Tests/Runtime/NetworkObjectDestroyWithSceneTests.cs b/testproject/Assets/Tests/Runtime/NetworkObjectDestroyWithSceneTests.cs index ad5fe5e1b0..57a2660601 100644 --- a/testproject/Assets/Tests/Runtime/NetworkObjectDestroyWithSceneTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkObjectDestroyWithSceneTests.cs @@ -10,6 +10,9 @@ namespace TestProject.RuntimeTests { [TestFixture(HostOrServer.DAHost)] [TestFixture(HostOrServer.Host)] +#if UNIFIED_NETCODE + [TestFixture(HostOrServer.UnifiedHost)] +#endif internal class NetworkObjectDestroyWithSceneTests : NetcodeIntegrationTest { private const string k_SceneToLoad = "EmptyScene"; @@ -98,7 +101,7 @@ public IEnumerator DestroyWithScene() // Depending on network topology, spawn the object with the appropriate owner. var owner = m_DistributedAuthority ? m_NotSessionOwner : m_SessionOwner; - m_SpawnedInstance = SpawnObject(m_TestPrefab.gameObject, m_NotSessionOwner, true).GetComponent(); + m_SpawnedInstance = SpawnObject(m_TestPrefab.gameObject, owner, true).GetComponent(); var instanceName = m_SpawnedInstance.name; yield return WaitForConditionOrTimeOut(() => ObjectSpawnedOnAllNetworkManagers(true)); diff --git a/testproject/Assets/Tests/Runtime/NetworkObjectSpawning.cs b/testproject/Assets/Tests/Runtime/NetworkObjectSpawning.cs index 6ed56b04ed..1b1f0e8c32 100644 --- a/testproject/Assets/Tests/Runtime/NetworkObjectSpawning.cs +++ b/testproject/Assets/Tests/Runtime/NetworkObjectSpawning.cs @@ -9,8 +9,11 @@ namespace TestProject.RuntimeTests { - [TestFixture(NetworkTopologyTypes.ClientServer)] - [TestFixture(NetworkTopologyTypes.DistributedAuthority)] + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.Host)] +#if UNIFIED_NETCODE + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.UnifiedHost)] +#endif + [TestFixture(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost)] internal class NetworkObjectSpawning : NetcodeIntegrationTest { private const string k_SceneToLoad = "NetworkObjectSpawnerTest"; @@ -27,7 +30,7 @@ protected override bool UseCMBService() return false; } - public NetworkObjectSpawning(NetworkTopologyTypes networkTopology) : base(networkTopology) { } + public NetworkObjectSpawning(NetworkTopologyTypes networkTopology, HostOrServer hostOrServer) : base(networkTopology, hostOrServer) { } protected override IEnumerator OnSetup() diff --git a/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventDataTests.cs b/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventDataTests.cs index a37a3244d2..f1bdc67c66 100644 --- a/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventDataTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkSceneManager/SceneEventDataTests.cs @@ -38,12 +38,10 @@ public IEnumerator FastReaderAllocationTest() var networkManager = networkManagerGameObject.AddComponent(); var unityTransport = networkManagerGameObject.AddComponent(); - var prefabs = ScriptableObject.CreateInstance(); - prefabs.Add(new NetworkPrefab()); networkManager.NetworkConfig = new NetworkConfig() { ConnectionApproval = false, - Prefabs = new NetworkPrefabs { NetworkPrefabsLists = new List { prefabs } }, + Prefabs = new NetworkPrefabs { NetworkPrefabsLists = new List { } }, NetworkTransport = unityTransport }; diff --git a/testproject/Assets/Tests/Runtime/OnNetworkSpawnExceptionTests.cs b/testproject/Assets/Tests/Runtime/OnNetworkSpawnExceptionTests.cs index ea81ac8409..9752ca9b80 100644 --- a/testproject/Assets/Tests/Runtime/OnNetworkSpawnExceptionTests.cs +++ b/testproject/Assets/Tests/Runtime/OnNetworkSpawnExceptionTests.cs @@ -2,11 +2,12 @@ using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; +using NUnit.Framework; using Unity.Netcode; using Unity.Netcode.TestHelpers.Runtime; using UnityEngine; -using UnityEngine.Assertions; using UnityEngine.TestTools; +using Assert = UnityEngine.Assertions.Assert; using Random = UnityEngine.Random; namespace TestProject.RuntimeTests @@ -81,7 +82,11 @@ public override void OnNetworkDespawn() throw new Exception("Exception thrown in OnNetworkDespawn"); } } - + + [TestFixture(HostOrServer.Server)] +#if UNIFIED_NETCODE + [TestFixture(HostOrServer.UnifiedServer)] +#endif public class OnNetworkSpawnExceptionTests : NetcodeIntegrationTest { protected override int NumberOfClients => 1; @@ -101,6 +106,11 @@ protected override bool UseCMBService() return false; } + public OnNetworkSpawnExceptionTests(HostOrServer hostOrServer) : base(hostOrServer) + { + + } + [UnityTest] public IEnumerator WhenOnNetworkSpawnThrowsException_FutureOnNetworkSpawnsAreNotPrevented() { @@ -238,7 +248,6 @@ public IEnumerator WhenOnNetworkDespawnThrowsException_FutureOnNetworkDespawnsAr protected override IEnumerator OnSetup() { - m_UseHost = false; OnNetworkSpawnThrowsExceptionComponent.NumClientSpawns = 0; OnNetworkSpawnThrowsExceptionComponent.NumServerSpawns = 0; OnNetworkSpawnNoExceptionComponent.NumClientSpawns = 0; diff --git a/testproject/Assets/Tests/Runtime/PrefabExtendedTests.cs b/testproject/Assets/Tests/Runtime/PrefabExtendedTests.cs index 665590d342..8689074023 100644 --- a/testproject/Assets/Tests/Runtime/PrefabExtendedTests.cs +++ b/testproject/Assets/Tests/Runtime/PrefabExtendedTests.cs @@ -13,8 +13,12 @@ namespace TestProject.RuntimeTests { // DAMODE-TODO: When scene management is working in distributed authority mode we need to update this test - [TestFixture(SceneManagementTypes.SceneManagementEnabled)] - [TestFixture(SceneManagementTypes.SceneManagementDisabled)] + [TestFixture(SceneManagementTypes.SceneManagementEnabled, HostOrServer.Host)] + [TestFixture(SceneManagementTypes.SceneManagementDisabled, HostOrServer.Host)] +#if UNIFIED_NETCODE + [TestFixture(SceneManagementTypes.SceneManagementEnabled, HostOrServer.UnifiedHost)] + [TestFixture(SceneManagementTypes.SceneManagementDisabled, HostOrServer.UnifiedHost)] +#endif public class PrefabExtendedTests : NetcodeIntegrationTest { private const string k_PrefabTestScene = "PrefabTestScene"; @@ -42,7 +46,7 @@ protected override bool UseCMBService() return false; } - public PrefabExtendedTests(SceneManagementTypes sceneManagementType) + public PrefabExtendedTests(SceneManagementTypes sceneManagementType, HostOrServer hostOrServer) : base(hostOrServer) { m_SceneManagementEnabled = sceneManagementType == SceneManagementTypes.SceneManagementEnabled; } diff --git a/testproject/Assets/Tests/Runtime/RespawnInSceneObjectsAfterShutdown.cs b/testproject/Assets/Tests/Runtime/RespawnInSceneObjectsAfterShutdown.cs index 7dbdc2635f..857c14ee6f 100644 --- a/testproject/Assets/Tests/Runtime/RespawnInSceneObjectsAfterShutdown.cs +++ b/testproject/Assets/Tests/Runtime/RespawnInSceneObjectsAfterShutdown.cs @@ -8,8 +8,11 @@ namespace TestProject.RuntimeTests { - [TestFixture(NetworkTopologyTypes.DistributedAuthority)] - [TestFixture(NetworkTopologyTypes.ClientServer)] + [TestFixture(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost)] + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.Host)] +#if UNIFIED_NETCODE + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.UnifiedHost)] +#endif public class RespawnInSceneObjectsAfterShutdown : NetcodeIntegrationTest { public const string SceneToLoad = "InSceneNetworkObject"; @@ -23,7 +26,7 @@ protected override bool UseCMBService() return false; } - public RespawnInSceneObjectsAfterShutdown(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } + public RespawnInSceneObjectsAfterShutdown(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) : base(networkTopologyType, hostOrServer) { } protected override void OnOneTimeSetup() { diff --git a/testproject/Assets/Tests/Runtime/RpcObserverTests.cs b/testproject/Assets/Tests/Runtime/RpcObserverTests.cs index b71c7e03dd..66d9834996 100644 --- a/testproject/Assets/Tests/Runtime/RpcObserverTests.cs +++ b/testproject/Assets/Tests/Runtime/RpcObserverTests.cs @@ -18,6 +18,10 @@ namespace TestProject.RuntimeTests [TestFixture(HostOrServer.DAHost)] [TestFixture(HostOrServer.Host)] [TestFixture(HostOrServer.Server)] +#if UNIFIED_NETCODE + [TestFixture(HostOrServer.UnifiedHost)] + [TestFixture(HostOrServer.UnifiedServer)] +#endif public class RpcObserverTests : NetcodeIntegrationTest { protected override int NumberOfClients => 9; @@ -155,6 +159,10 @@ private IEnumerator RunRpcObserverTest(List nonObservers) [UnityTest] public IEnumerator DespawnRespawnObserverTest() { + if (m_allPrefabsAsHybrid) + { + Assert.Ignore("Hybrid spawning does not support despawn-without-destroy."); + } var nonObservers = new List(); m_ServerRpcObserverObject.ResetTest(); // Wait for all clients to report they have spawned an instance of our test prefab diff --git a/testproject/Assets/Tests/Runtime/RpcTestsAutomated.cs b/testproject/Assets/Tests/Runtime/RpcTestsAutomated.cs index 228bfbfdd5..704c0ed10c 100644 --- a/testproject/Assets/Tests/Runtime/RpcTestsAutomated.cs +++ b/testproject/Assets/Tests/Runtime/RpcTestsAutomated.cs @@ -10,6 +10,10 @@ namespace TestProject.RuntimeTests { + [TestFixture(HostOrServer.Host)] +#if UNIFIED_NETCODE + [TestFixture(HostOrServer.UnifiedHost)] +#endif public class RpcTestsAutomated : NetcodeIntegrationTest { private bool m_TimedOut; @@ -23,6 +27,11 @@ protected override bool UseCMBService() return false; } + public RpcTestsAutomated(HostOrServer hostOrServer) : base(hostOrServer) + { + + } + protected override NetworkManagerInstatiationMode OnSetIntegrationTestMode() { return NetworkManagerInstatiationMode.DoNotCreate; diff --git a/testproject/Assets/Tests/Runtime/RpcUserSerializableTypesTest.cs b/testproject/Assets/Tests/Runtime/RpcUserSerializableTypesTest.cs index ae10ea60c9..5a92112f32 100644 --- a/testproject/Assets/Tests/Runtime/RpcUserSerializableTypesTest.cs +++ b/testproject/Assets/Tests/Runtime/RpcUserSerializableTypesTest.cs @@ -49,8 +49,11 @@ public void NetworkSerialize(BufferSerializer } - [TestFixture(NetworkTopologyTypes.DistributedAuthority)] - [TestFixture(NetworkTopologyTypes.ClientServer)] + [TestFixture(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost)] + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.Host)] +#if UNIFIED_NETCODE + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.UnifiedHost)] +#endif public class RpcUserSerializableTypesTest : NetcodeIntegrationTest { private UserSerializableClass m_UserSerializableClass; @@ -88,7 +91,7 @@ protected override bool UseCMBService() return false; } - public RpcUserSerializableTypesTest(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } + public RpcUserSerializableTypesTest(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) : base(networkTopologyType, hostOrServer) { } protected override NetworkManagerInstatiationMode OnSetIntegrationTestMode() { diff --git a/testproject/Assets/Tests/Runtime/SceneObjectsNotDestroyedOnShutdownTest.cs b/testproject/Assets/Tests/Runtime/SceneObjectsNotDestroyedOnShutdownTest.cs index f82b7ed400..3fcc9feae6 100644 --- a/testproject/Assets/Tests/Runtime/SceneObjectsNotDestroyedOnShutdownTest.cs +++ b/testproject/Assets/Tests/Runtime/SceneObjectsNotDestroyedOnShutdownTest.cs @@ -9,8 +9,11 @@ namespace TestProject.RuntimeTests { - [TestFixture(NetworkTopologyTypes.ClientServer)] - [TestFixture(NetworkTopologyTypes.DistributedAuthority)] + [TestFixture(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost)] + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.Host)] +#if UNIFIED_NETCODE + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.UnifiedHost)] +#endif public class SceneObjectsNotDestroyedOnShutdownTest : NetcodeIntegrationTest { protected override int NumberOfClients => 0; @@ -20,7 +23,7 @@ public class SceneObjectsNotDestroyedOnShutdownTest : NetcodeIntegrationTest private Scene m_TestScene; private WaitForSeconds m_DefaultWaitForTick = new(1.0f / 30); - public SceneObjectsNotDestroyedOnShutdownTest(NetworkTopologyTypes topology) : base(topology) { } + public SceneObjectsNotDestroyedOnShutdownTest(NetworkTopologyTypes topology, HostOrServer hostOrServer) : base(topology, hostOrServer) { } [UnityTest] public IEnumerator SceneObjectsNotDestroyedOnShutdown() diff --git a/testproject/Assets/Tests/Runtime/SenderIdTests.cs b/testproject/Assets/Tests/Runtime/SenderIdTests.cs index 92ebf2f4a1..e42fe4ae84 100644 --- a/testproject/Assets/Tests/Runtime/SenderIdTests.cs +++ b/testproject/Assets/Tests/Runtime/SenderIdTests.cs @@ -10,12 +10,18 @@ namespace TestProject.RuntimeTests { + [TestFixture(HostOrServer.Host)] +#if UNIFIED_NETCODE + [TestFixture(HostOrServer.UnifiedHost)] +#endif public class SenderIdTests : NetcodeIntegrationTest { protected override int NumberOfClients => 2; private NetworkManager FirstClient => m_ClientNetworkManagers[0]; private NetworkManager SecondClient => m_ClientNetworkManagers[1]; + + public SenderIdTests(HostOrServer hostOrServer) : base(hostOrServer) { } [UnityTest] public IEnumerator WhenSendingMessageFromServerToClient_SenderIdIsCorrect() diff --git a/testproject/Assets/Tests/Runtime/ServerDisconnectsClientTest.cs b/testproject/Assets/Tests/Runtime/ServerDisconnectsClientTest.cs index c16cceda66..cd730b2099 100644 --- a/testproject/Assets/Tests/Runtime/ServerDisconnectsClientTest.cs +++ b/testproject/Assets/Tests/Runtime/ServerDisconnectsClientTest.cs @@ -9,8 +9,11 @@ namespace TestProject.RuntimeTests { - [TestFixture(NetworkTopologyTypes.DistributedAuthority)] - [TestFixture(NetworkTopologyTypes.ClientServer)] + [TestFixture(NetworkTopologyTypes.DistributedAuthority, HostOrServer.DAHost)] + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.Host)] +#if UNIFIED_NETCODE + [TestFixture(NetworkTopologyTypes.ClientServer, HostOrServer.UnifiedHost)] +#endif public class ServerDisconnectsClientTest : NetcodeIntegrationTest { protected override int NumberOfClients => 1; @@ -21,7 +24,7 @@ protected override bool UseCMBService() return false; } - public ServerDisconnectsClientTest(NetworkTopologyTypes networkTopologyType) : base(networkTopologyType) { } + public ServerDisconnectsClientTest(NetworkTopologyTypes networkTopologyType, HostOrServer hostOrServer) : base(networkTopologyType, hostOrServer) { } protected override void OnCreatePlayerPrefab() { diff --git a/testproject/Assets/Tests/Runtime/TestProject.Runtime.Tests.asmdef b/testproject/Assets/Tests/Runtime/TestProject.Runtime.Tests.asmdef index 1bd9925469..c7028b927d 100644 --- a/testproject/Assets/Tests/Runtime/TestProject.Runtime.Tests.asmdef +++ b/testproject/Assets/Tests/Runtime/TestProject.Runtime.Tests.asmdef @@ -34,6 +34,11 @@ "name": "com.unity.addressables", "expression": "", "define": "TESTPROJECT_USE_ADDRESSABLES" + }, + { + "name": "com.unity.netcode", + "expression": "1.10.1", + "define": "UNIFIED_NETCODE" } ], "noEngineReferences": false diff --git a/testproject/Packages/manifest.json b/testproject/Packages/manifest.json index f7832aaad0..e64bb3bdad 100644 --- a/testproject/Packages/manifest.json +++ b/testproject/Packages/manifest.json @@ -1,23 +1,25 @@ { "disableProjectUpdate": false, "dependencies": { - "com.unity.addressables": "2.7.4", - "com.unity.ai.navigation": "2.0.9", - "com.unity.collab-proxy": "2.10.1", - "com.unity.ide.rider": "3.0.38", - "com.unity.ide.visualstudio": "2.0.25", - "com.unity.mathematics": "1.3.3", - "com.unity.multiplayer.tools": "2.2.6", + "com.unity.addressables": "2.9.1", + "com.unity.ai.navigation": "2.0.12", + "com.unity.collab-proxy": "2.12.4", + "com.unity.entities": "6.5.0", + "com.unity.ide.rider": "3.0.40", + "com.unity.ide.visualstudio": "2.0.26", + "com.unity.mathematics": "1.4.0", + "com.unity.multiplayer.tools": "2.2.8", + "com.unity.netcode": "6.6.0", "com.unity.netcode.gameobjects": "file:../../com.unity.netcode.gameobjects", "com.unity.package-validation-suite": "0.49.0-preview", - "com.unity.services.authentication": "3.5.2", - "com.unity.services.multiplayer": "1.2.0", - "com.unity.test-framework": "1.6.0", - "com.unity.test-framework.performance": "3.2.0", - "com.unity.timeline": "1.8.9", - "com.unity.toolchain.win-x86_64-linux-x86_64": "2.0.11", - "com.unity.ugui": "2.0.0", + "com.unity.services.authentication": "3.6.1", + "com.unity.services.multiplayer": "2.1.3", + "com.unity.test-framework": "1.8.0", + "com.unity.test-framework.performance": "3.4.0", + "com.unity.timeline": "1.8.12", + "com.unity.ugui": "2.6.0", "com.unity.modules.accessibility": "1.0.0", + "com.unity.modules.adaptiveperformance": "1.0.0", "com.unity.modules.ai": "1.0.0", "com.unity.modules.androidjni": "1.0.0", "com.unity.modules.animation": "1.0.0", @@ -31,10 +33,12 @@ "com.unity.modules.particlesystem": "1.0.0", "com.unity.modules.physics": "1.0.0", "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.physicscore2d": "1.0.0", "com.unity.modules.screencapture": "1.0.0", "com.unity.modules.terrain": "1.0.0", "com.unity.modules.terrainphysics": "1.0.0", "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.timelinefoundation": "1.0.0", "com.unity.modules.ui": "1.0.0", "com.unity.modules.uielements": "1.0.0", "com.unity.modules.umbra": "1.0.0", @@ -44,9 +48,9 @@ "com.unity.modules.unitywebrequestaudio": "1.0.0", "com.unity.modules.unitywebrequesttexture": "1.0.0", "com.unity.modules.unitywebrequestwww": "1.0.0", + "com.unity.modules.vectorgraphics": "1.0.0", "com.unity.modules.vehicles": "1.0.0", "com.unity.modules.video": "1.0.0", - "com.unity.modules.vr": "1.0.0", "com.unity.modules.wind": "1.0.0", "com.unity.modules.xr": "1.0.0" }, diff --git a/testproject/Packages/packages-lock.json b/testproject/Packages/packages-lock.json index 675de94bf2..00988aa549 100644 --- a/testproject/Packages/packages-lock.json +++ b/testproject/Packages/packages-lock.json @@ -1,7 +1,7 @@ { "dependencies": { "com.unity.addressables": { - "version": "2.7.4", + "version": "2.9.1", "depth": 0, "source": "registry", "dependencies": { @@ -11,13 +11,13 @@ "com.unity.modules.jsonserialize": "1.0.0", "com.unity.modules.imageconversion": "1.0.0", "com.unity.modules.unitywebrequest": "1.0.0", - "com.unity.scriptablebuildpipeline": "2.4.3", + "com.unity.scriptablebuildpipeline": "2.6.1", "com.unity.modules.unitywebrequestassetbundle": "1.0.0" }, "url": "https://packages.unity.com" }, "com.unity.ai.navigation": { - "version": "2.0.9", + "version": "2.0.12", "depth": 0, "source": "registry", "dependencies": { @@ -26,7 +26,7 @@ "url": "https://packages.unity.com" }, "com.unity.burst": { - "version": "1.8.25", + "version": "1.8.29", "depth": 1, "source": "registry", "dependencies": { @@ -36,33 +36,52 @@ "url": "https://packages.unity.com" }, "com.unity.collab-proxy": { - "version": "2.10.1", + "version": "2.12.4", "depth": 0, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, "com.unity.collections": { - "version": "2.6.2", + "version": "6.5.0", "depth": 1, - "source": "registry", + "source": "builtin", "dependencies": { - "com.unity.burst": "1.8.23", - "com.unity.mathematics": "1.3.2", + "com.unity.burst": "1.8.25", + "com.unity.nuget.mono-cecil": "1.11.6", "com.unity.test-framework": "1.4.6", - "com.unity.nuget.mono-cecil": "1.11.5", - "com.unity.test-framework.performance": "3.0.3" - }, - "url": "https://packages.unity.com" + "com.unity.test-framework.performance": "3.2.0" + } + }, + "com.unity.entities": { + "version": "6.5.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.burst": "1.8.25", + "com.unity.collections": "6.5.0", + "com.unity.nuget.mono-cecil": "1.11.6", + "com.unity.profiling.core": "1.0.3", + "com.unity.scriptablebuildpipeline": "1.23.1", + "com.unity.serialization": "6.5.0", + "com.unity.test-framework.performance": "3.2.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.hierarchy": "1.0.0" + } }, "com.unity.ext.nunit": { - "version": "2.0.5", + "version": "2.1.0", "depth": 1, "source": "builtin", "dependencies": {} }, "com.unity.ide.rider": { - "version": "3.0.38", + "version": "3.0.40", "depth": 0, "source": "registry", "dependencies": { @@ -71,23 +90,22 @@ "url": "https://packages.unity.com" }, "com.unity.ide.visualstudio": { - "version": "2.0.25", + "version": "2.0.26", "depth": 0, "source": "registry", "dependencies": { - "com.unity.test-framework": "1.1.31" + "com.unity.test-framework": "1.1.33" }, "url": "https://packages.unity.com" }, "com.unity.mathematics": { - "version": "1.3.3", + "version": "1.4.0", "depth": 0, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" + "source": "builtin", + "dependencies": {} }, "com.unity.multiplayer.tools": { - "version": "2.2.6", + "version": "2.2.8", "depth": 0, "source": "registry", "dependencies": { @@ -101,6 +119,16 @@ }, "url": "https://packages.unity.com" }, + "com.unity.netcode": { + "version": "6.6.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.transport": "6.5.0", + "com.unity.entities": "6.5.0", + "com.unity.modules.animation": "1.0.0" + } + }, "com.unity.netcode.gameobjects": { "version": "file:../../com.unity.netcode.gameobjects", "depth": 0, @@ -111,14 +139,14 @@ } }, "com.unity.nuget.mono-cecil": { - "version": "1.11.5", + "version": "1.11.6", "depth": 1, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, "com.unity.nuget.newtonsoft-json": { - "version": "3.2.1", + "version": "3.2.2", "depth": 1, "source": "registry", "dependencies": {}, @@ -134,14 +162,14 @@ "url": "https://packages.unity.com" }, "com.unity.profiling.core": { - "version": "1.0.2", + "version": "1.0.3", "depth": 1, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, "com.unity.scriptablebuildpipeline": { - "version": "2.4.3", + "version": "2.6.1", "depth": 1, "source": "registry", "dependencies": { @@ -150,8 +178,17 @@ }, "url": "https://packages.unity.com" }, + "com.unity.serialization": { + "version": "6.5.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.collections": "2.1.2", + "com.unity.burst": "1.7.2" + } + }, "com.unity.services.authentication": { - "version": "3.5.2", + "version": "3.6.1", "depth": 0, "source": "registry", "dependencies": { @@ -163,7 +200,7 @@ "url": "https://packages.unity.com" }, "com.unity.services.core": { - "version": "1.15.1", + "version": "1.16.0", "depth": 1, "source": "registry", "dependencies": { @@ -174,7 +211,7 @@ "url": "https://packages.unity.com" }, "com.unity.services.deployment": { - "version": "1.6.2", + "version": "1.7.2", "depth": 1, "source": "registry", "dependencies": { @@ -184,44 +221,44 @@ "url": "https://packages.unity.com" }, "com.unity.services.deployment.api": { - "version": "1.1.2", + "version": "1.1.3", "depth": 2, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, "com.unity.services.multiplayer": { - "version": "1.2.0", + "version": "2.1.3", "depth": 0, "source": "registry", "dependencies": { - "com.unity.transport": "2.5.0", + "com.unity.transport": "2.6.0", "com.unity.collections": "2.2.1", - "com.unity.services.qos": "1.3.0", - "com.unity.services.core": "1.15.1", - "com.unity.services.wire": "1.4.0", - "com.unity.services.deployment": "1.6.2", - "com.unity.nuget.newtonsoft-json": "3.2.1", + "com.unity.services.qos": "1.4.1", + "com.unity.services.core": "1.16.0", + "com.unity.services.wire": "1.4.1", + "com.unity.services.deployment": "1.7.1", + "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.modules.unitywebrequest": "1.0.0", - "com.unity.services.authentication": "3.5.1" + "com.unity.services.authentication": "3.6.0" }, "url": "https://packages.unity.com" }, "com.unity.services.qos": { - "version": "1.3.0", + "version": "1.4.1", "depth": 1, "source": "registry", "dependencies": { "com.unity.collections": "1.2.4", - "com.unity.services.core": "1.12.4", + "com.unity.services.core": "1.12.5", "com.unity.nuget.newtonsoft-json": "3.0.2", "com.unity.modules.unitywebrequest": "1.0.0", - "com.unity.services.authentication": "2.0.0" + "com.unity.services.authentication": "3.5.2" }, "url": "https://packages.unity.com" }, "com.unity.services.wire": { - "version": "1.4.0", + "version": "1.4.2", "depth": 1, "source": "registry", "dependencies": { @@ -231,34 +268,18 @@ }, "url": "https://packages.unity.com" }, - "com.unity.sysroot": { - "version": "2.0.10", - "depth": 1, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" - }, - "com.unity.sysroot.linux-x86_64": { - "version": "2.0.9", - "depth": 1, - "source": "registry", - "dependencies": { - "com.unity.sysroot": "2.0.10" - }, - "url": "https://packages.unity.com" - }, "com.unity.test-framework": { - "version": "1.6.0", + "version": "1.8.0", "depth": 0, "source": "builtin", "dependencies": { - "com.unity.ext.nunit": "2.0.3", + "com.unity.ext.nunit": "2.1.0", "com.unity.modules.imgui": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0" } }, "com.unity.test-framework.performance": { - "version": "3.2.0", + "version": "3.4.0", "depth": 0, "source": "registry", "dependencies": { @@ -268,7 +289,7 @@ "url": "https://packages.unity.com" }, "com.unity.timeline": { - "version": "1.8.9", + "version": "1.8.12", "depth": 0, "source": "registry", "dependencies": { @@ -279,34 +300,26 @@ }, "url": "https://packages.unity.com" }, - "com.unity.toolchain.win-x86_64-linux-x86_64": { - "version": "2.0.11", - "depth": 0, - "source": "registry", - "dependencies": { - "com.unity.sysroot": "2.0.10", - "com.unity.sysroot.linux-x86_64": "2.0.9" - }, - "url": "https://packages.unity.com" - }, "com.unity.transport": { - "version": "2.6.0", + "version": "6.5.0", "depth": 1, - "source": "registry", + "source": "builtin", "dependencies": { + "com.unity.collections": "6.5.0", "com.unity.burst": "1.8.24", - "com.unity.collections": "2.2.1", - "com.unity.mathematics": "1.3.2" - }, - "url": "https://packages.unity.com" + "com.unity.mathematics": "1.4.0" + } }, "com.unity.ugui": { - "version": "2.0.0", + "version": "2.6.0", "depth": 0, "source": "builtin", "dependencies": { "com.unity.modules.ui": "1.0.0", - "com.unity.modules.imgui": "1.0.0" + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.physics": "1.0.0" } }, "com.unity.modules.accessibility": { @@ -315,6 +328,14 @@ "source": "builtin", "dependencies": {} }, + "com.unity.modules.adaptiveperformance": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.subsystems": "1.0.0" + } + }, "com.unity.modules.ai": { "version": "1.0.0", "depth": 0, @@ -325,7 +346,9 @@ "version": "1.0.0", "depth": 0, "source": "builtin", - "dependencies": {} + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0" + } }, "com.unity.modules.animation": { "version": "1.0.0", @@ -362,6 +385,16 @@ "com.unity.modules.animation": "1.0.0" } }, + "com.unity.modules.hierarchy": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.hierarchycore": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.imgui": "1.0.0" + } + }, "com.unity.modules.hierarchycore": { "version": "1.0.0", "depth": 1, @@ -399,6 +432,14 @@ "dependencies": {} }, "com.unity.modules.physics2d": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physicscore2d": "1.0.0" + } + }, + "com.unity.modules.physicscore2d": { "version": "1.0.0", "depth": 0, "source": "builtin", @@ -443,6 +484,14 @@ "com.unity.modules.physics2d": "1.0.0" } }, + "com.unity.modules.timelinefoundation": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0" + } + }, "com.unity.modules.ui": { "version": "1.0.0", "depth": 0, @@ -458,7 +507,8 @@ "com.unity.modules.imgui": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0", "com.unity.modules.hierarchycore": "1.0.0", - "com.unity.modules.physics": "1.0.0" + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.animation": "1.0.0" } }, "com.unity.modules.umbra": { @@ -522,32 +572,32 @@ "com.unity.modules.imageconversion": "1.0.0" } }, - "com.unity.modules.vehicles": { + "com.unity.modules.vectorgraphics": { "version": "1.0.0", "depth": 0, "source": "builtin", "dependencies": { - "com.unity.modules.physics": "1.0.0" + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0" } }, - "com.unity.modules.video": { + "com.unity.modules.vehicles": { "version": "1.0.0", "depth": 0, "source": "builtin", "dependencies": { - "com.unity.modules.audio": "1.0.0", - "com.unity.modules.ui": "1.0.0", - "com.unity.modules.unitywebrequest": "1.0.0" + "com.unity.modules.physics": "1.0.0" } }, - "com.unity.modules.vr": { + "com.unity.modules.video": { "version": "1.0.0", "depth": 0, "source": "builtin", "dependencies": { - "com.unity.modules.jsonserialize": "1.0.0", - "com.unity.modules.physics": "1.0.0", - "com.unity.modules.xr": "1.0.0" + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" } }, "com.unity.modules.wind": { diff --git a/testproject/ProjectSettings/PackageManagerSettings.asset b/testproject/ProjectSettings/PackageManagerSettings.asset index b01b2f8da9..6e57db2799 100644 --- a/testproject/ProjectSettings/PackageManagerSettings.asset +++ b/testproject/ProjectSettings/PackageManagerSettings.asset @@ -12,32 +12,33 @@ MonoBehaviour: m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: - m_EnablePreviewPackages: 1 - m_EnablePackageDependencies: 1 + m_EnablePreReleasePackages: 0 m_AdvancedSettingsExpanded: 1 m_ScopedRegistriesSettingsExpanded: 1 + m_SeeAllPackageVersions: 0 + m_DismissPreviewPackagesInUse: 0 oneTimeWarningShown: 1 - m_Registries: - - m_Id: main + oneTimePackageErrorsPopUpShown: 0 + m_MainRegistry: + m_Id: main m_Name: m_Url: https://packages.unity.com m_Scopes: [] m_IsDefault: 1 + m_IsUnityRegistry: 1 m_Capabilities: 7 + m_ConfigSource: 0 + m_Compliance: + m_Status: 0 + m_Violations: [] + m_ScopedRegistries: [] m_UserSelectedRegistryName: m_UserAddingNewScopedRegistry: 0 m_RegistryInfoDraft: - m_ErrorMessage: - m_Original: - m_Id: - m_Name: - m_Url: - m_Scopes: [] - m_IsDefault: 0 - m_Capabilities: 0 m_Modified: 0 - m_Name: - m_Url: - m_Scopes: - - - m_SelectedScopeIndex: 0 + m_ErrorMessage: + m_UserModificationsEntityId: + m_rawData: 568105584918791443 + m_OriginalEntityId: + m_rawData: 568105584918791444 + m_LoadAssets: 0 diff --git a/testproject/ProjectSettings/ProjectSettings.asset b/testproject/ProjectSettings/ProjectSettings.asset index 3bb16ba357..06561ea008 100644 --- a/testproject/ProjectSettings/ProjectSettings.asset +++ b/testproject/ProjectSettings/ProjectSettings.asset @@ -3,7 +3,7 @@ --- !u!129 &1 PlayerSettings: m_ObjectHideFlags: 0 - serializedVersion: 28 + serializedVersion: 30 productGUID: bba99b16607b94720b7d04f7f1a82989 AndroidProfiler: 0 AndroidFilterTouchesWhenObscured: 0 @@ -41,7 +41,6 @@ PlayerSettings: height: 1 m_SplashScreenLogos: [] m_VirtualRealitySplashScreen: {fileID: 0} - m_HolographicTrackingLossScreen: {fileID: 0} defaultScreenWidth: 1280 defaultScreenHeight: 720 defaultScreenWidthWeb: 960 @@ -66,10 +65,15 @@ PlayerSettings: useOSAutorotation: 1 use32BitDisplayBuffer: 1 preserveFramebufferAlpha: 0 + adjustIOSFPSUsingThermalState: 1 + thermalStateSeriousIOSFPS: 30 + thermalStateCriticalIOSFPS: 15 disableDepthAndStencilBuffers: 0 androidStartInFullscreen: 1 androidRenderOutsideSafeArea: 1 androidUseSwappy: 1 + androidRequestedVisibleInsets: 0 + androidSystemBarsBehavior: 2 androidDisplayOptions: 1 androidBlitType: 0 androidResizeableActivity: 0 @@ -84,6 +88,7 @@ PlayerSettings: defaultIsNativeResolution: 1 macRetinaSupport: 1 runInBackground: 1 + callOnDisableOnAssetBundleUnload: 1 muteOtherAudioSources: 0 Prepare IOS For Recording: 0 Force IOS Speakers When Recording: 0 @@ -114,6 +119,7 @@ PlayerSettings: xboxEnableGuest: 0 xboxEnablePIXSampling: 0 metalFramebufferOnly: 0 + metalUseMetalDisplayLink: 0 xboxOneResolution: 0 xboxOneSResolution: 0 xboxOneXResolution: 3 @@ -147,12 +153,10 @@ PlayerSettings: preloadedAssets: [] metroInputSource: 0 wsaTransparentSwapchain: 0 - m_HolographicPauseOnTrackingLoss: 1 xboxOneDisableKinectGpuReservation: 1 xboxOneEnable7thCore: 1 vrSettings: enable360StereoCapture: 0 - isWsaHolographicRemotingEnabled: 0 enableFrameTimingStats: 0 enableOpenGLProfilerGPURecorders: 1 allowHDRDisplaySupport: 0 @@ -174,9 +178,10 @@ PlayerSettings: tvOS: 0 overrideDefaultApplicationIdentifier: 0 AndroidBundleVersionCode: 1 - AndroidMinSdkVersion: 23 + AndroidMinSdkVersion: 26 AndroidTargetSdkVersion: 0 AndroidPreferredInstallLocation: 1 + AndroidPreferredDataLocation: 1 aotOptions: nimt-trampolines=1024 stripEngineCode: 1 iPhoneStrippingLevel: 0 @@ -191,13 +196,14 @@ PlayerSettings: VertexChannelCompressionMask: 4054 iPhoneSdkVersion: 988 iOSSimulatorArchitecture: 0 - iOSTargetOSVersionString: 13.0 + iOSTargetOSVersionString: 15.0 tvOSSdkVersion: 0 tvOSSimulatorArchitecture: 0 tvOSRequireExtendedGameController: 0 - tvOSTargetOSVersionString: 13.0 + tvOSTargetOSVersionString: 15.0 VisionOSSdkVersion: 0 VisionOSTargetOSVersionString: 1.0 + xcodeProjectType: 0 uIPrerenderedIcon: 0 uIRequiresPersistentWiFi: 0 uIRequiresFullScreen: 1 @@ -451,12 +457,6 @@ PlayerSettings: - m_BuildTarget: WindowsStandaloneSupport m_APIs: 0200000012000000 m_Automatic: 0 - m_BuildTargetVRSettings: - - m_BuildTarget: Standalone - m_Enabled: 0 - m_Devices: - - Oculus - - OpenVR m_DefaultShaderChunkSizeInMB: 16 m_DefaultShaderChunkCount: 0 openGLRequireES31: 0 @@ -484,7 +484,7 @@ PlayerSettings: locationUsageDescription: microphoneUsageDescription: bluetoothUsageDescription: - macOSTargetOSVersion: 11.0 + macOSTargetOSVersion: 12.0 switchNMETAOverride: switchNetLibKey: switchSocketMemoryPoolSize: 6144 @@ -630,6 +630,8 @@ PlayerSettings: switchMicroSleepForYieldTime: 25 switchRamDiskSpaceSize: 12 switchUpgradedPlayerSettingsToNMETA: 0 + switchCaStoreSource: 0 + switchCaStoreFilePath: ps4NPAgeRating: 12 ps4NPTitleSecret: ps4NPTrophyPackPath: @@ -739,7 +741,7 @@ PlayerSettings: webWasm2023: 0 webEnableSubmoduleStrippingCompatibility: 0 scriptingDefineSymbols: - Standalone: UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT + Standalone: UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT;NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL;NETCODE_EXPERIMENTAL_SINGLE_WORLD_HOST;OUT_OF_BAND_RPC additionalCompilerArguments: Standalone: - -warnaserror @@ -747,6 +749,7 @@ PlayerSettings: scriptingBackend: {} il2cppCompilerConfiguration: {} il2cppCodeGeneration: {} + il2cppLTOMode: {} il2cppStacktraceInformation: {} managedStrippingLevel: EmbeddedLinux: 1 @@ -794,8 +797,7 @@ PlayerSettings: metroDefaultTileSize: 1 metroTileForegroundText: 2 metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} - metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, - a: 1} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} metroSplashScreenUseBackgroundColor: 0 syncCapabilities: 0 platformCapabilities: {} @@ -831,7 +833,6 @@ PlayerSettings: XboxOneXTitleMemory: 8 XboxOneOverrideIdentityName: XboxOneOverrideIdentityPublisher: - vrEditorSettings: {} cloudServicesEnabled: Analytics: 0 Build: 0 @@ -862,6 +863,7 @@ PlayerSettings: captureStartupLogs: {} activeInputHandler: 0 windowsGamepadBackendHint: 0 + enableDirectStorage: 0 cloudProjectId: framebufferDepthMemorylessMode: 0 qualitySettingsNames: [] @@ -877,3 +879,4 @@ PlayerSettings: androidVulkanAllowFilterList: [] androidVulkanDeviceFilterListAsset: {fileID: 0} d3d12DeviceFilterListAsset: {fileID: 0} + allowedHttpConnections: 3