diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
index 25b86e3da0..508180ea63 100644
--- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
@@ -1071,7 +1071,7 @@ public void SetSingleton()
OnSingletonReady?.Invoke();
}
- private void Awake()
+ protected virtual void Awake()
{
if (Log == null)
{
@@ -1088,7 +1088,7 @@ private void Awake()
OnInstantiated?.Invoke(this);
}
- private void OnEnable()
+ protected virtual void OnEnable()
{
if (RunInBackground)
{
@@ -1337,6 +1337,11 @@ private bool CanStart(StartType type)
/// returns true if started in server mode successfully; otherwise false
public bool StartServer()
{
+ if (Log == null)
+ {
+ Log = new ContextualLogger(this, false);
+ Log.Warning(new Context(LogLevel.Normal, "No logger defined. Ensure base.Awake() and base.OnEnable is called in any derived NetworkManager classes."));
+ }
Log.CaptureFunctionCall();
if (!CanStart(StartType.Server))
@@ -1397,6 +1402,11 @@ public bool StartServer()
/// (/) returns true if started in client mode successfully.
public bool StartClient()
{
+ if (Log == null)
+ {
+ Log = new ContextualLogger(this, false);
+ Log.Warning(new Context(LogLevel.Normal, "No logger defined. Ensure base.Awake() and base.OnEnable is called in any derived NetworkManager classes."));
+ }
Log.CaptureFunctionCall();
if (!CanStart(StartType.Client))
@@ -1450,6 +1460,11 @@ public bool StartClient()
/// (/) returns true if started in host mode successfully.
public bool StartHost()
{
+ if (Log == null)
+ {
+ Log = new ContextualLogger(this, false);
+ Log.Warning(new Context(LogLevel.Normal, "No logger defined. Ensure base.Awake() and base.OnEnable is called in any derived NetworkManager classes."));
+ }
Log.CaptureFunctionCall();
if (!CanStart(StartType.Host))
@@ -1752,8 +1767,14 @@ private void OnApplicationQuit()
}
// Note that this gets also called manually by OnSceneUnloaded and OnApplicationQuit
- private void OnDestroy()
+ protected virtual void OnDestroy()
{
+ if (Log == null)
+ {
+ Log = new ContextualLogger(this, false);
+ Log.Warning(new Context(LogLevel.Normal, "No logger defined. Ensure base.Awake() and base.OnEnable is called in any derived NetworkManager classes."));
+ }
+
try
{
ShutdownInternal();
diff --git a/testproject/Assets/Tests/Runtime/NetworkManagerTests.cs b/testproject/Assets/Tests/Runtime/NetworkManagerTests.cs
index ccf46cb61c..e1262bd920 100644
--- a/testproject/Assets/Tests/Runtime/NetworkManagerTests.cs
+++ b/testproject/Assets/Tests/Runtime/NetworkManagerTests.cs
@@ -198,4 +198,45 @@ private void OnServerStopped(bool obj)
m_ServerNetworkManager.Shutdown();
}
}
+
+ internal class DerivedNetworkManagerTests
+ {
+ private class TestNetworkManager : NetworkManager
+ {
+ public void Awake() { }
+ public void OnEnable() { }
+ }
+
+ [UnityTest]
+ public IEnumerator ValidateDerivedNetworkManager()
+ {
+ var gameObject = new GameObject("TestNetworkManager");
+ var server = gameObject.AddComponent();
+ var mockTransport = server.gameObject.AddComponent();
+ server.NetworkConfig ??= new NetworkConfig();
+ server.NetworkConfig.NetworkTransport = mockTransport;
+ var client = Object.Instantiate(server);
+
+ var isListening = server.StartServer();
+ Assert.That(isListening, Is.True, "Server failed to start!");
+
+ client.StartClient();
+
+ var timeoutHelper = new TimeoutHelper();
+ yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(() => client.IsListening, timeoutHelper);
+ Assert.That(timeoutHelper.TimedOut, Is.False, "Client timed out waiting to connect!");
+
+ Object.Destroy(client.gameObject);
+
+ server.Shutdown();
+ timeoutHelper = new TimeoutHelper();
+ yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(() => !server.IsListening, timeoutHelper);
+ Assert.That(timeoutHelper.TimedOut, Is.False, "Timed out waiting for server to shutdown!");
+
+ isListening = server.StartHost();
+ Assert.That(isListening, Is.True, "Host failed to start!");
+
+ Object.Destroy(gameObject);
+ }
+ }
}