diff --git a/Examples/PingTool/Assets/DefaultNetworkPrefabs.asset b/Examples/PingTool/Assets/DefaultNetworkPrefabs.asset index 073f4484e8..72cef84a6d 100644 --- a/Examples/PingTool/Assets/DefaultNetworkPrefabs.asset +++ b/Examples/PingTool/Assets/DefaultNetworkPrefabs.asset @@ -15,12 +15,12 @@ MonoBehaviour: IsDefault: 1 List: - Override: 0 - Prefab: {fileID: 2522762726852386808, guid: 380c984d34fc8664c8f53fc1d8733a25, type: 3} + Prefab: {fileID: 8921789205124766477, guid: 89b57e576a8d47643b2dbd45b1f8cab1, type: 3} SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} - Override: 0 - Prefab: {fileID: 8921789205124766477, guid: 89b57e576a8d47643b2dbd45b1f8cab1, type: 3} + Prefab: {fileID: 4874009706086500699, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} SourcePrefabToOverride: {fileID: 0} SourceHashToOverride: 0 OverridingTargetPrefab: {fileID: 0} diff --git a/Examples/PingTool/Assets/PingTool/PingTool.cs b/Examples/PingTool/Assets/PingTool/PingTool.cs index e27887d503..32b0da0fa8 100644 --- a/Examples/PingTool/Assets/PingTool/PingTool.cs +++ b/Examples/PingTool/Assets/PingTool/PingTool.cs @@ -28,6 +28,8 @@ public class PingTool : NetworkBehaviour public bool StartWithNetStateMonitorHidden = true; public KeyCode NetStatsMonitorToggle = KeyCode.Tab; #endif + public Text PingRateValue; + public Text PingToolHelp; public bool EnableConsoleLogging = true; public UnityEvent LogMessage; @@ -65,7 +67,7 @@ public void Reset() private Dictionary m_NextClientPingTime = new Dictionary(); private Dictionary m_ClientUpdateRoutines = new Dictionary(); private Slider m_Slider; - private Text m_PingRateValue; + private Canvas m_PingUICanvas; private bool m_PingRateUpdated; private float m_LastUpdatedTime; @@ -93,7 +95,6 @@ public ClientRtt GetClientRtt(ulong clientID) private void Awake() { m_Slider = GetComponentInChildren(); - m_PingRateValue = GetComponentInChildren(); m_PingUICanvas = GetComponentInChildren(); m_PingUICanvas.gameObject.SetActive(false); #if MULTIPLAYER_TOOLS @@ -102,6 +103,11 @@ private void Awake() m_NetStatsMonitor.Visible = false; } #endif + + if (PingToolHelp) + { + PingToolHelp.text = PingToolHelp.text.Replace("<>", $"<{NetStatsMonitorToggle}>"); + } } protected override void OnNetworkPreSpawn(ref NetworkManager networkManager) @@ -156,11 +162,19 @@ public override void OnNetworkSpawn() InitializeAllClients(); NetworkManager.OnConnectionEvent += OnConnectionEvent; } + UpdatePingRateValue(m_PingRate.Value); - m_PingRateValue.text = $"{m_PingRate.Value}"; base.OnNetworkSpawn(); } + private void UpdatePingRateValue(int value) + { + if (PingRateValue) + { + PingRateValue.text = $"{m_PingRate.Value}"; + } + } + protected override void OnOwnershipChanged(ulong previous, ulong current) { if (current == NetworkManager.LocalClientId) @@ -182,7 +196,7 @@ protected override void OnOwnershipChanged(ulong previous, ulong current) private void OnPingRateChanged(int previous, int current) { InitializePingClientTime(OwnerClientId); - m_PingRateValue.text = $"{current}"; + UpdatePingRateValue(current); } public override void OnNetworkDespawn() @@ -290,7 +304,7 @@ private void OnPingRateChanged() if (m_Slider.value != PingRate) { PingRate = (int)m_Slider.value; - m_PingRateValue.text = $"{PingRate}"; + UpdatePingRateValue(PingRate); // Flag the last time this value updated for the OwnerMonitorPingRateChange coroutine m_LastUpdatedTime = Time.realtimeSinceStartup; m_PingRateUpdated = true; @@ -377,6 +391,10 @@ private void Update() if (m_NetStatsMonitor && Input.GetKeyDown(NetStatsMonitorToggle)) { m_NetStatsMonitor.Visible = !m_NetStatsMonitor.Visible; + if (PingToolHelp) + { + PingToolHelp.gameObject.SetActive(!m_NetStatsMonitor.Visible); + } } } } @@ -422,12 +440,24 @@ private void InitializeClient(ulong clientId, bool hasEntry) [Rpc(SendTo.SpecifiedInParams)] private void PingRpc(float timeSent, RpcParams rpcParams) { + // Exit early if despawning or shutdown + if (!IsSpawned || NetworkManager == null || !NetworkManager.IsListening || NetworkManager.ShutdownInProgress) + { + return; + } + PongRpc(Mathf.Abs(NetworkManager.ServerTime.TimeAsFloat - timeSent), RpcTarget.Single(rpcParams.Receive.SenderClientId, RpcTargetUse.Temp)); } [Rpc(SendTo.SpecifiedInParams)] private void PongRpc(float timeDelta, RpcParams rpcParams) { + // Exit early if despawning or shutdown + if (!IsSpawned || NetworkManager == null || !NetworkManager.IsListening || NetworkManager.ShutdownInProgress) + { + return; + } + UpdateClientRTT(rpcParams.Receive.SenderClientId, timeDelta); } @@ -448,7 +478,7 @@ private void UpdateClientRTT(ulong clientId, float timeDelta) } var pingEntry = m_ClientPingQueue[clientId]; - var ping = timeDelta - (latencyToTimeServer * 0.001f); + var ping = Mathf.Abs(timeDelta - (latencyToTimeServer * 0.001f)); pingEntry.PingTime += ping; pingEntry.UTP_RTT += currentRTT; pingEntry.ReceivedPongs++; diff --git a/Examples/PingTool/Assets/PingTool/PingTool.prefab b/Examples/PingTool/Assets/PingTool/PingTool.prefab index 84c17c5ced..b36922c89a 100644 --- a/Examples/PingTool/Assets/PingTool/PingTool.prefab +++ b/Examples/PingTool/Assets/PingTool/PingTool.prefab @@ -31,6 +31,7 @@ RectTransform: m_LocalScale: {x: 0, y: 0, z: 0} m_ConstrainProportionsScale: 0 m_Children: + - {fileID: 1251000097366145441} - {fileID: 6277513074320060017} - {fileID: 4052611471472719404} - {fileID: 4428071759692496771} @@ -543,7 +544,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: GlobalObjectIdHash: 1175888021 - InScenePlacedSourceGlobalObjectIdHash: 0 + InScenePlacedSourceGlobalObjectIdHash: 290216032 DeferredDespawnTick: 0 Ownership: 2 AlwaysReplicateAsRoot: 0 @@ -553,6 +554,8 @@ MonoBehaviour: SpawnWithObservers: 1 DontDestroyWithOwner: 1 AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 --- !u!114 &2592079281344418938 MonoBehaviour: m_ObjectHideFlags: 0 @@ -565,14 +568,108 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 1466a9d81cf83ff45bca7014cb93c010, type: 3} m_Name: m_EditorClassIdentifier: + ShowTopMostFoldoutHeaderGroup: 1 PingRate: 2 StartWithNetStateMonitorHidden: 1 NetStatsMonitorToggle: 9 + PingRateValue: {fileID: 3165861447957584369} + PingToolHelp: {fileID: 7873216060197180850} EnableConsoleLogging: 0 LogMessage: m_PersistentCalls: - m_Calls: [] + m_Calls: + - m_Target: {fileID: 0} + m_TargetAssemblyTypeName: NetworkManagerHelper, Assembly-CSharp + m_MethodName: LogPingToolMessage + m_Mode: 0 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 m_NetStatsMonitor: {fileID: 1263430958893551039} +--- !u!1 &6370153036591290436 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1251000097366145441} + - component: {fileID: 277549501682696586} + - component: {fileID: 7873216060197180850} + m_Layer: 5 + m_Name: PingToolHelper + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1251000097366145441 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6370153036591290436} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 8751044705753477979} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 132.5, y: 25.600006} + m_SizeDelta: {x: 260, y: 24} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &277549501682696586 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6370153036591290436} + m_CullTransparentMesh: 1 +--- !u!114 &7873216060197180850 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6370153036591290436} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 0.4606132, b: 0, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 18 + m_FontStyle: 1 + m_BestFit: 0 + m_MinSize: 0 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Hit To Show PingTool --- !u!1 &7349017088681708274 GameObject: m_ObjectHideFlags: 0 diff --git a/Examples/PingTool/Assets/Scenes/SampleScene.unity b/Examples/PingTool/Assets/Scenes/SampleScene.unity index 593d861048..b880ffe45e 100644 --- a/Examples/PingTool/Assets/Scenes/SampleScene.unity +++ b/Examples/PingTool/Assets/Scenes/SampleScene.unity @@ -42,7 +42,8 @@ RenderSettings: --- !u!157 &3 LightmapSettings: m_ObjectHideFlags: 0 - serializedVersion: 12 + serializedVersion: 13 + m_BakeOnSceneLoad: 0 m_GISettings: serializedVersion: 2 m_BounceScale: 1 @@ -145,7 +146,7 @@ RectTransform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 28232985} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -154,7 +155,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0.5, y: 0} m_AnchorMax: {x: 0.5, y: 0} - m_AnchoredPosition: {x: 0, y: 40} + m_AnchoredPosition: {x: 0, y: 25} m_SizeDelta: {x: 180, y: 30} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &28232987 @@ -222,6 +223,8 @@ MonoBehaviour: SpawnWithObservers: 1 DontDestroyWithOwner: 0 AutoObjectParentSync: 1 + SyncOwnerTransformWhenParented: 1 + AllowOwnerToParent: 0 --- !u!114 &28232990 MonoBehaviour: m_ObjectHideFlags: 0 @@ -234,6 +237,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 6637cd674efb56a48a3d4d545d23a8d3, type: 3} m_Name: m_EditorClassIdentifier: + ShowTopMostFoldoutHeaderGroup: 1 --- !u!1 &455857869 GameObject: m_ObjectHideFlags: 0 @@ -243,12 +247,10 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 455857870} - - component: {fileID: 455857873} - - component: {fileID: 455857871} - component: {fileID: 455857872} - - component: {fileID: 455857874} + - component: {fileID: 455857871} m_Layer: 0 - m_Name: NetworkManager + m_Name: ExtNetworkManager m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -307,32 +309,17 @@ MonoBehaviour: m_GameObject: {fileID: 455857869} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: e4d8d44c602b97b47ba488a40c66267c, type: 3} - m_Name: - m_EditorClassIdentifier: - ConnectionType: 1 - EnableVSync: 0 - TargetFrameRate: 100 - m_OriginalVSyncCount: 0 ---- !u!114 &455857873 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 455857869} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 593a2fe42fa9d37498c96f9a383b6521, type: 3} + m_Script: {fileID: 11500000, guid: 9639343147b80384d98dd77ff33767d4, type: 3} m_Name: m_EditorClassIdentifier: + NetworkManagerExpanded: 1 NetworkConfig: ProtocolVersion: 0 NetworkTransport: {fileID: 455857871} PlayerPrefab: {fileID: 8921789205124766477, guid: 89b57e576a8d47643b2dbd45b1f8cab1, type: 3} Prefabs: NetworkPrefabsLists: - - {fileID: 11400000, guid: 3d25a2b1f6c12ee47bf7601c2edd7e70, type: 2} + - {fileID: 11400000, guid: aa82390bfdde2564f828b8e5be375282, type: 2} TickRate: 30 ClientConnectionBufferTimeout: 10 ConnectionApproval: 0 @@ -356,19 +343,11 @@ MonoBehaviour: OldPrefabList: [] RunInBackground: 1 LogLevel: 1 ---- !u!114 &455857874 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 455857869} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 09865cca13a4bec439963971d7296b02, type: 3} - m_Name: - m_EditorClassIdentifier: - NetworkManager: {fileID: 455857873} + ExtendedNetworkManagerExpanded: 1 + ConnectionType: 1 + TargetFrameRate: 100 + EnableVSync: 0 + m_OriginalVSyncCount: 1 --- !u!1 &479361661 GameObject: m_ObjectHideFlags: 0 @@ -417,12 +396,12 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} m_Name: m_EditorClassIdentifier: - m_UiScaleMode: 0 + m_UiScaleMode: 1 m_ReferencePixelsPerUnit: 100 m_ScaleFactor: 1 - m_ReferenceResolution: {x: 800, y: 600} + m_ReferenceResolution: {x: 1280, y: 720} m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 + m_MatchWidthOrHeight: 0.5 m_PhysicalUnit: 3 m_FallbackScreenDPI: 96 m_DefaultSpriteDPI: 96 @@ -576,6 +555,10 @@ PrefabInstance: serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: + - target: {fileID: 1251000097366145441, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} + propertyPath: m_AnchoredPosition.x + value: 134.3 + objectReference: {fileID: 0} - target: {fileID: 2569679938784265262, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} propertyPath: m_LocalPosition.x value: 0 @@ -620,14 +603,6 @@ PrefabInstance: propertyPath: LogMessage.m_PersistentCalls.m_Calls.Array.size value: 1 objectReference: {fileID: 0} - - target: {fileID: 2592079281344418938, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} - propertyPath: LogMessage.m_PersistentCalls.m_Calls.Array.data[0].m_Mode - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 2592079281344418938, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} - propertyPath: LogMessage.m_PersistentCalls.m_Calls.Array.data[0].m_Target - value: - objectReference: {fileID: 455857872} - target: {fileID: 2592079281344418938, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} propertyPath: LogMessage.m_PersistentCalls.m_Calls.Array.data[0].m_CallState value: 2 @@ -668,9 +643,13 @@ PrefabInstance: propertyPath: m_AnchorMax.y value: 0 objectReference: {fileID: 0} - - target: {fileID: 6057903054739576449, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} - propertyPath: m_LocalPosition.y - value: 0 + - target: {fileID: 7873216060197180850, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} + propertyPath: m_Text + value: <> Toggles PingTool + objectReference: {fileID: 0} + - target: {fileID: 7873216060197180850, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} + propertyPath: m_FontData.m_Alignment + value: 3 objectReference: {fileID: 0} - target: {fileID: 9070511216422219346, guid: 3f5e8ae5613c82a4f9f859c11a4f2e09, type: 3} propertyPath: GlobalObjectIdHash diff --git a/Examples/PingTool/Assets/Scripts/NetworkManagerHelper.cs b/Examples/PingTool/Assets/Scripts/ExtendedNetworkManager.cs similarity index 54% rename from Examples/PingTool/Assets/Scripts/NetworkManagerHelper.cs rename to Examples/PingTool/Assets/Scripts/ExtendedNetworkManager.cs index 3c06675415..2c291bbe89 100644 --- a/Examples/PingTool/Assets/Scripts/NetworkManagerHelper.cs +++ b/Examples/PingTool/Assets/Scripts/ExtendedNetworkManager.cs @@ -3,38 +3,107 @@ using System.Linq; using System.Threading.Tasks; using Unity.Netcode; -using Unity.Netcode.Examples.PingTool; -using Unity.Netcode.Transports.UTP; using Unity.Services.Authentication; using Unity.Services.Core; using Unity.Services.Multiplayer; using UnityEngine; +using SessionState = Unity.Services.Multiplayer.SessionState; +#if UNITY_EDITOR +using Unity.Netcode.Editor; +using UnityEditor; + +/// +/// The custom editor for the component. +/// +[CustomEditor(typeof(ExtendedNetworkManager), true)] +[CanEditMultipleObjects] +public class ExtendedNetworkManagerEditor : NetworkManagerEditor +{ + private SerializedProperty m_ConnectionType; + private SerializedProperty m_TargetFrameRate; + private SerializedProperty m_EnableVSync; + + public override void OnEnable() + { + m_ConnectionType = serializedObject.FindProperty(nameof(ExtendedNetworkManager.ConnectionType)); + m_TargetFrameRate = serializedObject.FindProperty(nameof(ExtendedNetworkManager.TargetFrameRate)); + m_EnableVSync = serializedObject.FindProperty(nameof(ExtendedNetworkManager.EnableVSync)); + base.OnEnable(); + } + + private void DisplayExtendedNetworkManagerProperties() + { + EditorGUILayout.PropertyField(m_ConnectionType); + EditorGUILayout.PropertyField(m_TargetFrameRate); + EditorGUILayout.PropertyField(m_EnableVSync); + } + + public override void OnInspectorGUI() + { + var extendedNetworkManager = target as ExtendedNetworkManager; + // Handle switching the appropriate connection type based on the network topology + // Host connectio type can be set for client-server and distributed authority + // Live Service can only be used with distributed authority + // Client-server can only be used with a host connection type + var connectionTypes = Enum.GetValues(typeof(ExtendedNetworkManager.ConnectionTypes)); + var connectionType = ExtendedNetworkManager.ConnectionTypes.LiveService; + if (m_ConnectionType.enumValueIndex > 0 && m_ConnectionType.enumValueIndex < connectionTypes.Length) + { + connectionType = (ExtendedNetworkManager.ConnectionTypes)connectionTypes.GetValue(m_ConnectionType.enumValueIndex); + } + void SetExpanded(bool expanded) { extendedNetworkManager.ExtendedNetworkManagerExpanded = expanded; }; + DrawFoldOutGroup(extendedNetworkManager.GetType(), DisplayExtendedNetworkManagerProperties, extendedNetworkManager.ExtendedNetworkManagerExpanded, SetExpanded); + + var updatedConnectedType = (ExtendedNetworkManager.ConnectionTypes)connectionTypes.GetValue(m_ConnectionType.enumValueIndex); + if (connectionType == updatedConnectedType && updatedConnectedType == ExtendedNetworkManager.ConnectionTypes.LiveService && extendedNetworkManager.NetworkConfig.NetworkTopology == NetworkTopologyTypes.ClientServer) + { + extendedNetworkManager.ConnectionType = ExtendedNetworkManager.ConnectionTypes.Host; + } + else if (connectionType == ExtendedNetworkManager.ConnectionTypes.Host && updatedConnectedType == ExtendedNetworkManager.ConnectionTypes.LiveService && extendedNetworkManager.NetworkConfig.NetworkTopology == NetworkTopologyTypes.ClientServer) + { + extendedNetworkManager.NetworkConfig.NetworkTopology = NetworkTopologyTypes.DistributedAuthority; + } + base.OnInspectorGUI(); + } +} +#endif -public class NetworkManagerHelper : MonoBehaviour + + +public class ExtendedNetworkManager : NetworkManager { - public static NetworkManagerHelper Instance; +#if UNITY_EDITOR + // Inspector view expand/collapse settings for this derived child class + [HideInInspector] + public bool ExtendedNetworkManagerExpanded; +#endif + + public static ExtendedNetworkManager Instance; public enum ConnectionTypes { - Service, + LiveService, Host, } - - [Tooltip("The connection type. When set to service, it will connect to the local service. When host, it will use the standard host connection.")] public ConnectionTypes ConnectionType; - [Tooltip("Enables or disables VSynch.")] - public bool EnableVSync = false; - - [Tooltip("Sets the desired target frame rate.")] public int TargetFrameRate = 100; + public bool EnableVSync = false; [HideInInspector] [SerializeField] private int m_OriginalVSyncCount; - private NetworkManager m_NetworkManager; +#if UNITY_EDITOR + + protected override void OnValidateComponent() + { + m_OriginalVSyncCount = QualitySettings.vSyncCount; + base.OnValidateComponent(); + } +#endif + private ISession m_CurrentSession; private string m_SessionName; @@ -50,19 +119,6 @@ private enum ConnectionStates private ConnectionStates m_ConnectionState; -#if UNITY_EDITOR - private void OnValidate() - { - m_NetworkManager = GetComponent(); - m_OriginalVSyncCount = QualitySettings.vSyncCount; - } -#endif - - public void LogPingToolMessage(ulong clientId, PingTool.ClientRtt clientRtt) - { - LogMessage($"[Client-{clientId}] Ping: {clientRtt.Ping * 1000}ms | RTT: {clientRtt.RTT}ms", 5); - } - public static string GetRandomString(int length) { var r = new System.Random(); @@ -79,11 +135,14 @@ private void Awake() { Screen.SetResolution((int)(Screen.currentResolution.width * 0.40f), (int)(Screen.currentResolution.height * 0.40f), FullScreenMode.Windowed); SetFrameRate(TargetFrameRate, EnableVSync); - m_NetworkManager = GetComponent(); + SetSingleton(); } private async void Start() { + OnClientConnectedCallback += OnClientConnected; + OnClientDisconnectCallback += OnClientDisconnect; + OnConnectionEvent += OnClientConnectionEvent; if (UnityServices.Instance != null && UnityServices.Instance.State != ServicesInitializationState.Initialized) { await UnityServices.InitializeAsync(); @@ -101,6 +160,13 @@ private async void Start() } } + private void OnDestroy() + { + OnClientConnectedCallback -= OnClientConnected; + OnClientDisconnectCallback -= OnClientDisconnect; + OnConnectionEvent -= OnClientConnectionEvent; + } + private void SignedIn() { AuthenticationService.Instance.SignedIn -= SignedIn; @@ -119,54 +185,32 @@ private void OnDrawLiveServiceGUI() if (GUILayout.Button("Create or Connect To Session")) { - m_NetworkManager.NetworkConfig.UseCMBService = true; - m_NetworkManager.OnClientStopped += OnClientStopped; - m_NetworkManager.OnClientStarted += OnClientStarted; + NetworkConfig.UseCMBService = true; + OnClientStopped += ClientStopped; + OnClientStarted += ClientStarted; m_SessionTask = ConnectThroughLiveService(); m_ConnectionState = ConnectionStates.Connecting; LogMessage($"Connecting to session {m_SessionName}..."); } } - private void OnDrawLocalServiceGUI() - { - var unityTransport = m_NetworkManager.NetworkConfig.NetworkTransport as UnityTransport; - GUILayout.Label("IP Address:", GUILayout.Width(100)); - unityTransport.ConnectionData.Address = GUILayout.TextField(unityTransport.ConnectionData.Address, GUILayout.Width(100)); - - GUILayout.Label("Port:", GUILayout.Width(100)); - var portString = GUILayout.TextField(unityTransport.ConnectionData.Port.ToString(), GUILayout.Width(100)); - ushort.TryParse(portString, out unityTransport.ConnectionData.Port); - - // CMB distributed authority services just "connects" with no host, client, or server option (all are clients) - if (GUILayout.Button("Start Client")) - { - m_NetworkManager.NetworkConfig.UseCMBService = true; - m_NetworkManager.OnClientStopped += OnClientStopped; - m_NetworkManager.OnClientStarted += OnClientStarted; - m_NetworkManager.StartClient(); - m_ConnectionState = ConnectionStates.Connecting; - } - } - private void OnDrawDAHostGUI() { if (GUILayout.Button("Start Host")) { - m_NetworkManager.OnClientStopped += OnClientStopped; - m_NetworkManager.OnClientStarted += OnClientStarted; - m_NetworkManager.StartHost(); + OnClientStopped += ClientStopped; + OnClientStarted += ClientStarted; + StartHost(); } if (GUILayout.Button("Start Client")) { - m_NetworkManager.OnClientStopped += OnClientStopped; - m_NetworkManager.OnClientStarted += OnClientStarted; - m_NetworkManager.StartClient(); + OnClientStopped += ClientStopped; + OnClientStarted += ClientStarted; + StartClient(); } } - private void OnUpdateGUIDisconnected() { GUILayout.BeginArea(new Rect(10, 10, 300, 800)); @@ -174,14 +218,14 @@ private void OnUpdateGUIDisconnected() GUILayout.Label("Session Name", GUILayout.Width(100)); var connectionType = ConnectionType; - if (m_NetworkManager.NetworkConfig.NetworkTopology == NetworkTopologyTypes.ClientServer && connectionType != ConnectionTypes.Service) + if (NetworkConfig.NetworkTopology == NetworkTopologyTypes.ClientServer && connectionType != ConnectionTypes.Host) { connectionType = ConnectionTypes.Host; } switch (connectionType) { - case ConnectionTypes.Service: + case ConnectionTypes.LiveService: { OnDrawLiveServiceGUI(); break; @@ -194,22 +238,41 @@ private void OnUpdateGUIDisconnected() } GUILayout.EndArea(); + + GUILayout.BeginArea(new Rect(10, Display.main.renderingHeight - 40, Display.main.renderingWidth - 10, 30)); + var scenesPreloaded = new System.Text.StringBuilder(); + scenesPreloaded.Append("Scenes Preloaded: "); + for (int i = 0; i < UnityEngine.SceneManagement.SceneManager.sceneCount; i++) + { + var scene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(i); + scenesPreloaded.Append($"[{scene.name}]"); + } + GUILayout.Label(scenesPreloaded.ToString()); + GUILayout.EndArea(); } private void OnUpdateGUIConnected() { - GUILayout.BeginArea(new Rect(10, 10, 800, 40)); - if (m_NetworkManager.CMBServiceConnection) + if (CMBServiceConnection) { + GUILayout.BeginArea(new Rect(10, 10, 800, 800)); GUILayout.Label($"Session: {m_SessionName}"); + GUILayout.EndArea(); } else { - var unityTransport = m_NetworkManager.NetworkConfig.NetworkTransport as UnityTransport; - GUILayout.Label($"IP: {unityTransport.ConnectionData.Address} : {unityTransport.ConnectionData.Port}"); - } + GUILayout.BeginArea(new Rect(10, 10, 800, 800)); + if (DistributedAuthorityMode) + { + GUILayout.Label($"DAHosted Session"); + } + else + { + GUILayout.Label($"Client-Server Session"); + } - GUILayout.EndArea(); + GUILayout.EndArea(); + } GUILayout.BeginArea(new Rect(Display.main.renderingWidth - 160, 10, 150, 80)); @@ -222,7 +285,7 @@ private void OnUpdateGUIConnected() } else { - m_NetworkManager.Shutdown(); + Shutdown(); } } @@ -262,16 +325,16 @@ private void OnGUI() GUILayout.EndArea(); } - private void OnClientStarted() + private void ClientStarted() { - m_NetworkManager.OnClientStarted -= OnClientStarted; + OnClientStarted -= ClientStarted; m_ConnectionState = ConnectionStates.Connected; LogMessage($"Connected to session {m_SessionName}."); } - private void OnClientStopped(bool isHost) + private void ClientStopped(bool isHost) { - m_NetworkManager.OnClientStopped -= OnClientStopped; + OnClientStopped -= ClientStopped; m_ConnectionState = ConnectionStates.None; m_SessionTask = null; m_CurrentSession = null; @@ -293,7 +356,6 @@ private async Task ConnectThroughLiveService() catch (Exception e) { LogMessage($"{e.Message}"); - m_ConnectionState = ConnectionStates.None; Debug.LogException(e); } return null; @@ -315,6 +377,21 @@ private void Update() } } + private void OnClientConnectionEvent(NetworkManager networkManager, ConnectionEventData eventData) + { + LogMessage($"[{Time.realtimeSinceStartup}] Connection event {eventData.EventType} for Client-{eventData.ClientId}."); + } + + private void OnClientConnected(ulong clientId) + { + LogMessage($"[{Time.realtimeSinceStartup}] Connected event invoked for Client-{clientId}."); + } + + private void OnClientDisconnect(ulong clientId) + { + LogMessage($"[{Time.realtimeSinceStartup}] Disconnected event invoked for Client-{clientId}."); + } + private List m_MessageLogs = new List(); private class MessageLog @@ -343,7 +420,7 @@ public void LogMessage(string msg, float timeToLive = 10.0f) Debug.Log(msg); } - public NetworkManagerHelper() + public ExtendedNetworkManager() { Instance = this; } diff --git a/Examples/PingTool/Assets/Scripts/ExtendedNetworkManager.cs.meta b/Examples/PingTool/Assets/Scripts/ExtendedNetworkManager.cs.meta new file mode 100644 index 0000000000..80b3f767c1 --- /dev/null +++ b/Examples/PingTool/Assets/Scripts/ExtendedNetworkManager.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9639343147b80384d98dd77ff33767d4 \ No newline at end of file diff --git a/Examples/PingTool/Assets/Scripts/NetworkManagerHelper.cs.meta b/Examples/PingTool/Assets/Scripts/NetworkManagerHelper.cs.meta deleted file mode 100644 index 6c3e265735..0000000000 --- a/Examples/PingTool/Assets/Scripts/NetworkManagerHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e4d8d44c602b97b47ba488a40c66267c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Examples/PingTool/Assets/Scripts/OnDisconnectNotify.cs b/Examples/PingTool/Assets/Scripts/OnDisconnectNotify.cs deleted file mode 100644 index 32ef99b677..0000000000 --- a/Examples/PingTool/Assets/Scripts/OnDisconnectNotify.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Unity.Netcode; -using UnityEngine; - -public class OnDisconnectNotify : MonoBehaviour -{ - public NetworkManager NetworkManager; - private void Start() - { - NetworkManager.OnClientConnectedCallback += OnClientConnectedCallback; - NetworkManager.OnClientDisconnectCallback += OnClientDisconnectCallback; - NetworkManager.OnConnectionEvent += OnConnectionEvent; - } - - private void OnConnectionEvent(NetworkManager networkManager, ConnectionEventData eventData) - { - NetworkManagerHelper.Instance.LogMessage($"[{Time.realtimeSinceStartup}] Connection event {eventData.EventType} for Client-{eventData.ClientId}."); - } - - private void OnClientConnectedCallback(ulong clientId) - { - NetworkManagerHelper.Instance.LogMessage($"[{Time.realtimeSinceStartup}] Connected event invoked for Client-{clientId}."); - } - - private void OnClientDisconnectCallback(ulong clientId) - { - NetworkManagerHelper.Instance.LogMessage($"[{Time.realtimeSinceStartup}] Disconnected event invoked for Client-{clientId}."); - } - - private void OnDestroy() - { - NetworkManager.OnClientConnectedCallback -= OnClientConnectedCallback; - NetworkManager.OnClientDisconnectCallback -= OnClientDisconnectCallback; - NetworkManager.OnConnectionEvent -= OnConnectionEvent; - } -} diff --git a/Examples/PingTool/Assets/Scripts/OnDisconnectNotify.cs.meta b/Examples/PingTool/Assets/Scripts/OnDisconnectNotify.cs.meta deleted file mode 100644 index 12549aa4f5..0000000000 --- a/Examples/PingTool/Assets/Scripts/OnDisconnectNotify.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 09865cca13a4bec439963971d7296b02 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Examples/PingTool/Assets/Scripts/ServerHostClientText.cs b/Examples/PingTool/Assets/Scripts/ServerHostClientText.cs index e2ff41dfa6..74dfdd7ada 100644 --- a/Examples/PingTool/Assets/Scripts/ServerHostClientText.cs +++ b/Examples/PingTool/Assets/Scripts/ServerHostClientText.cs @@ -8,7 +8,7 @@ public class ServerHostClientText : NetworkBehaviour private Color m_Color; private Color m_ColorAlpha; - private Vector3 m_LocalPosition; + private Vector3 m_AnchoredPosition3D; public void SetColor(Color color) { @@ -19,7 +19,8 @@ public void SetColor(Color color) private void Awake() { - m_LocalPosition = transform.localPosition; + // Get the anchored 3D position + m_AnchoredPosition3D = (transform as RectTransform).anchoredPosition3D; m_DisplayText = GetComponent(); } @@ -45,7 +46,8 @@ public override void OnNetworkSpawn() m_DisplayText.text = $"Client-{NetworkManager.LocalClientId}"; } } - transform.localPosition = m_LocalPosition; + // Apply the AnchoredPosition3D to account for any adjustments in resolution/size + (transform as RectTransform).anchoredPosition3D = m_AnchoredPosition3D; } public override void OnNetworkDespawn() diff --git a/Examples/PingTool/Packages/manifest.json b/Examples/PingTool/Packages/manifest.json index 82de3dac2a..45f1b14b65 100644 --- a/Examples/PingTool/Packages/manifest.json +++ b/Examples/PingTool/Packages/manifest.json @@ -3,22 +3,23 @@ "com.unity.2d.sprite": "1.0.0", "com.unity.2d.tilemap": "1.0.0", "com.unity.ads": "4.4.2", - "com.unity.ai.navigation": "2.0.0", + "com.unity.ai.navigation": "2.0.4", "com.unity.analytics": "3.8.1", - "com.unity.collab-proxy": "2.4.3", + "com.unity.collab-proxy": "2.5.2", "com.unity.feature.development": "1.0.2", "com.unity.ide.visualstudio": "2.0.22", - "com.unity.multiplayer.playmode": "1.1.0", - "com.unity.multiplayer.tools": "2.1.0", - "com.unity.netcode.gameobjects": "2.0.0-pre.3", - "com.unity.services.multiplayer": "1.0.0-pre.1", - "com.unity.test-framework": "1.4.4", + "com.unity.multiplayer.center": "1.0.0", + "com.unity.multiplayer.playmode": "1.3.0", + "com.unity.multiplayer.tools": "2.2.1", + "com.unity.netcode.gameobjects": "https://github.com/Unity-Technologies/com.unity.netcode.gameobjects.git?path=com.unity.netcode.gameobjects#develop-2.0.0", + "com.unity.services.multiplayer": "1.0.0", + "com.unity.test-framework": "1.4.5", "com.unity.timeline": "1.8.7", "com.unity.toolchain.win-x86_64-linux-x86_64": "2.0.9", "com.unity.transport": "2.3.0", "com.unity.ugui": "2.0.0", "com.unity.visualscripting": "1.9.4", - "com.unity.xr.legacyinputhelpers": "2.1.10", + "com.unity.xr.legacyinputhelpers": "2.1.11", "com.unity.modules.accessibility": "1.0.0", "com.unity.modules.ai": "1.0.0", "com.unity.modules.androidjni": "1.0.0",