diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
index 95f9605729..3b9f772682 100644
--- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
@@ -139,6 +139,11 @@ public bool DAHost
///
public event OnSessionOwnerPromotedDelegateHandler OnSessionOwnerPromoted;
+ ///
+ /// When a server or client is initializing, before the network connecting is established
+ ///
+ public event Action OnInitialized;
+
internal void SetSessionOwner(ulong sessionOwner)
{
var previousSessionOwner = CurrentSessionOwner;
@@ -1166,6 +1171,17 @@ internal void Initialize(bool server)
NetworkConfig.InitializePrefabs();
PrefabHandler.RegisterPlayerPrefab();
+
+ // Invoke initialized callback
+ try
+ {
+ OnInitialized?.Invoke();
+ }
+ catch (Exception)
+ {
+ Shutdown();
+ throw;
+ }
}
private enum StartType
diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerInitializedTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerInitializedTests.cs
new file mode 100644
index 0000000000..8fd9b08b43
--- /dev/null
+++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerInitializedTests.cs
@@ -0,0 +1,61 @@
+using System;
+using NUnit.Framework;
+using Unity.Netcode.Transports.UTP;
+using UnityEngine;
+using Object = UnityEngine.Object;
+
+namespace Unity.Netcode.RuntimeTests
+{
+ internal class NetworkManagerInitializedTests
+ {
+ [Test]
+ [TestCase(true)]
+ [TestCase(false)]
+ public void OnInitializedIsCalled(bool isServer)
+ {
+ var networkManagerObject = CreateNetworkManager(out var networkManager);
+
+ var callbackHit = false;
+
+ networkManager.OnInitialized += () => callbackHit = true;
+ networkManager.Initialize(isServer);
+
+ Assert.True(callbackHit, "OnInitialized callback was never triggered");
+
+ // Clean up
+ Object.Destroy(networkManagerObject);
+ }
+
+ [Test]
+ public void OnInitializedShutsDownOnException()
+ {
+ var networkManagerObject = CreateNetworkManager(out var networkManager);
+
+ networkManager.OnInitialized += () => throw new Exception();
+
+ try
+ {
+ networkManager.StartServer();
+ }
+ catch (Exception)
+ {
+ // do nothing
+ }
+
+ Assert.True(networkManager.ShutdownInProgress, "Manager did not shutdown");
+
+ // Clean up
+ Object.Destroy(networkManagerObject);
+ }
+
+ private GameObject CreateNetworkManager(out NetworkManager networkManager)
+ {
+ var networkManagerObject = new GameObject(nameof(OnInitializedIsCalled));
+
+ var unityTransport = networkManagerObject.AddComponent();
+ networkManager = networkManagerObject.AddComponent();
+ networkManager.NetworkConfig = new NetworkConfig() { NetworkTransport = unityTransport };
+ return networkManagerObject;
+ }
+ }
+}
diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerInitializedTests.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerInitializedTests.cs.meta
new file mode 100644
index 0000000000..62086a604b
--- /dev/null
+++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerInitializedTests.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: a8a60a1c41f9436a9d98d9773bed6f92
+timeCreated: 1721149159
\ No newline at end of file