diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/MoverScriptNoRigidbody.cs b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/MoverScriptNoRigidbody.cs
index abc1f5e0fc..5cc3865bfd 100644
--- a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/MoverScriptNoRigidbody.cs
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/MoverScriptNoRigidbody.cs
@@ -174,7 +174,9 @@ protected override void OnNetworkPostSpawn()
}
m_ParentedText?.gameObject.SetActive(true);
+#if !DEDICATED_SERVER
UpdateParentedText();
+#endif
base.OnNetworkPostSpawn();
}
@@ -201,7 +203,9 @@ public override void OnNetworkObjectParentChanged(NetworkObject parentNetworkObj
{
Debug.Log($"Parented under {parentNetworkObject.name}");
}
+#if !DEDICATED_SERVER
UpdateParentedText();
+#endif
base.OnNetworkObjectParentChanged(parentNetworkObject);
}
@@ -334,6 +338,7 @@ private void ApplyInput()
m_PlayerBallMotion.HasMotion(moveMotion);
}
+#if !DEDICATED_SERVER
///
/// Updates player TextMesh relative to each client's camera view
///
@@ -373,4 +378,5 @@ private void UpdateParentedText()
}
}
}
+#endif
}
diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkManagerBootstrapper.cs b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkManagerBootstrapper.cs
index bedc3ed758..da858b14ef 100644
--- a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkManagerBootstrapper.cs
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkManagerBootstrapper.cs
@@ -1,13 +1,23 @@
+#if !DEDICATED_SERVER || (DEDICATED_SERVER && !UNITY_EDITOR)
using System;
+#endif
using System.Collections.Generic;
using System.Linq;
+#if !DEDICATED_SERVER
using System.Threading.Tasks;
+#endif
using Unity.Netcode;
+#if !DEDICATED_SERVER
using Unity.Services.Authentication;
using Unity.Services.Core;
using Unity.Services.Multiplayer;
+#else
+using Unity.Netcode.Transports.UTP;
+#endif
using UnityEngine;
+#if !DEDICATED_SERVER
using SessionState = Unity.Services.Multiplayer.SessionState;
+#endif
#region NetworkManagerBootstrapperEditor
#if UNITY_EDITOR
@@ -67,7 +77,7 @@ protected override void OnValidateComponent()
base.OnValidateComponent();
}
#endif
- #endregion
+#endregion
#region Properties
public static NetworkManagerBootstrapper Instance;
@@ -98,12 +108,13 @@ private enum ConnectionStates
[SerializeField]
private bool m_ServicesRegistered;
+#if !DEDICATED_SERVER
private ISession m_CurrentSession;
private string m_SessionName;
private string m_ProfileName;
private Task m_SessionTask;
-
- #endregion
+#endif
+#endregion
#region Initialization and Destroy
public static string GetRandomString(int length)
@@ -120,12 +131,27 @@ public void SetFrameRate(int targetFrameRate, bool enableVsync)
private void Awake()
{
+#if !DEDICATED_SERVER
Screen.SetResolution((int)(Screen.currentResolution.width * 0.40f), (int)(Screen.currentResolution.height * 0.40f), FullScreenMode.Windowed);
SetFrameRate(TargetFrameRate, EnableVSync);
+#endif
SetSingleton();
m_SceneBootstrapLoader = GetComponent();
}
+#if DEDICATED_SERVER
+ private void Start()
+ {
+ m_SceneBootstrapLoader.OnMainMenuLoaded += OnMainMenuLoaded;
+ m_SceneBootstrapLoader.LoadMainMenu();
+ }
+
+ private void OnMainMenuLoaded()
+ {
+ m_SceneBootstrapLoader.OnMainMenuLoaded -= OnMainMenuLoaded;
+ StartDedicatedServer();
+ }
+#else
private async void Start()
{
OnClientConnectedCallback += OnClientConnected;
@@ -152,17 +178,20 @@ private async void Start()
}
}
m_SceneBootstrapLoader.LoadMainMenu();
- }
+ }
private void OnDestroy()
{
OnClientConnectedCallback -= OnClientConnected;
OnClientDisconnectCallback -= OnClientDisconnect;
OnConnectionEvent -= OnClientConnectionEvent;
}
- #endregion
+#endif
+#endregion
#region Session and Connection Event Handling
+
+#if !DEDICATED_SERVER
private void OnClientConnectionEvent(NetworkManager networkManager, ConnectionEventData eventData)
{
LogMessage($"[{Time.realtimeSinceStartup}] Connection event {eventData.EventType} for Client-{eventData.ClientId}.");
@@ -235,9 +264,11 @@ private async Task ConnectThroughLiveService()
}
return null;
}
- #endregion
+#endif
+#endregion
#region GUI Menu
+#if !DEDICATED_SERVER
public void StartOrConnectToDistributedAuthoritySession()
{
m_SessionTask = ConnectThroughLiveService();
@@ -364,9 +395,11 @@ private void OnGUI()
}
GUILayout.EndArea();
}
- #endregion
+#endif
+#endregion
#region Server Camera Handling
+#if !DEDICATED_SERVER
private Vector3 m_CameraOriginalPosition;
private Quaternion m_CameraOriginalRotation;
private int m_CurrentFollowPlayerIndex = -1;
@@ -438,9 +471,159 @@ public void ClearFollowPlayer()
SetCameraDefaults();
}
}
- #endregion
+#endif
+#endregion
#region Update Methods and Properties
+#if DEDICATED_SERVER
+ private UnityTransport m_UnityTransport;
+ ///
+ /// All of the dedicated server specific script logic is contained and only compiled when DEDICATED_SERVER is defined
+ ///
+
+ private void StartDedicatedServer()
+ {
+ m_UnityTransport = NetworkConfig.NetworkTransport as UnityTransport;
+ if (m_UnityTransport != null)
+ {
+ // Always good to know what scenes are currently loaded since you might have
+ // different scenes to load for a DGS vs client
+ 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}]");
+ }
+ Debug.Log(scenesPreloaded.ToString());
+
+ // Set the application frame rate to like 30 to reduce frame processing overhead
+ Application.targetFrameRate = 30;
+
+ Debug.Log($"[Pre-Init] Server Address Endpoint: {m_UnityTransport.ConnectionData.ServerEndPoint}");
+ Debug.Log($"[Pre-Init] Server Listen Endpoint: {m_UnityTransport.ConnectionData.ListenEndPoint}");
+ // Setup your IP and port sepcific to your DGS
+ //unityTransport.SetConnectionData(ListenAddress, ListenPort, ListenAddress);
+
+ //Debug.Log($"[Post-Init] Server Address Endpoint: {unityTransport.ConnectionData.ServerEndPoint}");
+ //Debug.Log($"[Post-Init] Server Listen Endpoint: {unityTransport.ConnectionData.ListenEndPoint}");
+
+ // Get the server started notification
+ OnServerStarted += ServerStarted;
+
+ // Start the server listening
+ m_SceneBootstrapLoader.StartSession(SceneBootstrapLoader.StartAsTypes.Server);
+ }
+ else
+ {
+ Debug.LogError("Failed to get the UnityTransport!");
+ }
+ }
+
+ ///
+ /// Register callbacks when the OnServerStarted callback is invoked.
+ /// This makes it easier to know you are registering for events only
+ /// when the server successfully has started.
+ ///
+ private void ServerStarted()
+ {
+ Debug.Log("Dedicated Server Started!");
+ Debug.Log($"[Started] Server Address Endpoint: {m_UnityTransport.ConnectionData.ServerEndPoint}");
+ Debug.Log($"[Started] Server Listen Endpoint: {m_UnityTransport.ConnectionData.ListenEndPoint}");
+ Debug.Log("===============================================================");
+ Debug.Log("[X] Exits session (Shutdown) | [ESC] Exits application instance");
+ Debug.Log("===============================================================");
+ OnServerStarted -= ServerStarted;
+ OnClientConnectedCallback += ClientConnectedCallback;
+ OnClientDisconnectCallback += ClientDisconnectCallback;
+ // Register for OnServerStopped
+ OnServerStopped += ServerStopped;
+ }
+
+ private void ServerStopped(bool obj)
+ {
+ OnClientConnectedCallback -= ClientConnectedCallback;
+ OnClientDisconnectCallback -= ClientDisconnectCallback;
+ OnServerStopped -= ServerStopped;
+ Debug.Log("Dedicated Server Stopped!");
+ Debug.Log("===============================================================");
+ Debug.Log("[S] Starts new session (StartServer) | [ESC] Exits application");
+ Debug.Log("===============================================================");
+ }
+
+ private void ClientConnectedCallback(ulong clientId)
+ {
+ Debug.Log($"Client-{clientId} connected and approved.");
+ }
+
+ private void ClientDisconnectCallback(ulong clientId)
+ {
+ Debug.Log($"Client-{clientId} disconnected.");
+ }
+
+#if UNITY_EDITOR
+ private void HandleEditorKeyCommands()
+ {
+ // Shutdown/Stop the server
+ if (Input.GetKeyDown(KeyCode.X) && IsListening && !ShutdownInProgress)
+ {
+ Shutdown();
+ }
+ else // Start the server (this example makes it automatically start when the application first starts)
+ if (Input.GetKeyDown(KeyCode.S) && !IsListening)
+ {
+ StartDedicatedServer();
+ }
+ }
+#else
+ private void HandleConsoleKeyCommands()
+ {
+ if (Console.KeyAvailable)
+ {
+ var networkManager = NetworkManager.Singleton;
+ var keyPressed = Console.ReadKey(true);
+ switch(keyPressed.Key)
+ {
+ case ConsoleKey.X:
+ {
+ if(networkManager.IsListening && !networkManager.ShutdownInProgress)
+ {
+ networkManager.Shutdown();
+ }
+ break;
+ }
+ case ConsoleKey.S:
+ {
+ if (!networkManager.IsListening && !networkManager.ShutdownInProgress)
+ {
+ StartDedicatedServer();
+ }
+ break;
+ }
+ case ConsoleKey.Escape:
+ {
+ Application.Quit();
+ break;
+ }
+ }
+ }
+ }
+#endif
+
+ ///
+ /// Update that is only included in the build and invoked when running as a dedicated server
+ ///
+ private void DedicatedServerUpdate()
+ {
+#if UNITY_EDITOR
+ HandleEditorKeyCommands();
+#else
+ HandleConsoleKeyCommands();
+#endif
+ }
+
+#else // End of DEDICATED_SERVER defined region
+
///
/// General update for server-side
///
@@ -459,9 +642,13 @@ private void ClientSideUpdate()
{
}
+#endif
private void Update()
{
+#if DEDICATED_SERVER
+ DedicatedServerUpdate();
+#else
if (IsListening)
{
if (IsServer)
@@ -473,6 +660,7 @@ private void Update()
ClientSideUpdate();
}
}
+#endif
if (m_MessageLogs.Count == 0)
{
@@ -487,6 +675,7 @@ private void Update()
}
}
}
+
#endregion
#region Message Logging
diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkPrefabOverrideHandler.cs b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkPrefabOverrideHandler.cs
index 7774f52d71..9bba90b13a 100644
--- a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkPrefabOverrideHandler.cs
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkPrefabOverrideHandler.cs
@@ -52,6 +52,7 @@ public NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaterni
public void Destroy(NetworkObject networkObject)
{
+#if !DEDICATED_SERVER
// Another useful thing about handling this instantiation and destruction of a NetworkObject is that you can do house cleaning
// prior to the object being destroyed. This handles the scenario where the server is following a player and the player disconnects.
// Before destroying the player object, we want to unparent the camera and reset the player being followed.
@@ -59,6 +60,7 @@ public void Destroy(NetworkObject networkObject)
{
m_NetworkManager.ClearFollowPlayer();
}
+#endif
Destroy(networkObject.gameObject);
}
}
diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/SceneBootstrapLoader.cs b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/SceneBootstrapLoader.cs
index 08642c10e1..256122618e 100644
--- a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/SceneBootstrapLoader.cs
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/SceneBootstrapLoader.cs
@@ -3,7 +3,6 @@
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
-
using UnityEngine;
using UnityEngine.SceneManagement;
#if UNITY_EDITOR
@@ -105,6 +104,8 @@ private void Awake()
m_NetworkManager = GetComponent();
}
+ public event Action OnMainMenuLoaded;
+
///
/// Should be invoked by bootstrap when first starting the applicaiton and should be loaded upon exiting
/// a session and shutting down the .
@@ -114,6 +115,7 @@ public void LoadMainMenu()
if (!m_NetworkManager.IsListening)
{
SceneManager.LoadScene(m_MainMenuScene, LoadSceneMode.Single);
+ OnMainMenuLoaded?.Invoke();
}
else
{
@@ -147,9 +149,6 @@ private void OnNetworkManagerShutdown(bool wasHost)
}
#region SCENE PRE & POST START LOADING METHODS
-
-
-
private IEnumerator PreSceneLoading(StartAsTypes startAsType)
{
var sceneDefines = startAsType == StartAsTypes.Client ? ClientSceneDefines : ServerSceneDefines;
@@ -188,11 +187,14 @@ private IEnumerator PreSceneLoading(StartAsTypes startAsType)
{
m_NetworkManager.StartServer();
}
+#if !DEDICATED_SERVER
else
{
m_NetworkManager.StartHost();
}
+#endif
}
+#if !DEDICATED_SERVER
else
{
m_NetworkManager.OnClientStopped += OnNetworkManagerShutdown;
@@ -209,6 +211,7 @@ private IEnumerator PreSceneLoading(StartAsTypes startAsType)
m_NetworkManager.StartClient();
}
}
+#endif
}
///
@@ -265,7 +268,7 @@ private void SceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
{
m_SceneJustLoaded = scene.name;
}
- #endregion
+#endregion
#region SERVER POST START CONFIGURATION AND ADDITIONAL SHARED SCENE LOADING
///
diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/ServerHostClientText.cs b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/ServerHostClientText.cs
index 93e150b2ba..1319e54b85 100644
--- a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/ServerHostClientText.cs
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/ServerHostClientText.cs
@@ -63,7 +63,9 @@ public override void OnNetworkDespawn()
base.OnNetworkDespawn();
}
+#if !DEDICATED_SERVER
private bool m_LastFocusedValue;
+
private void OnGUI()
{
if (!IsSpawned || m_LastFocusedValue == Application.isFocused)
@@ -82,4 +84,5 @@ private void OnGUI()
m_DisplayText.color = m_ColorAlpha;
}
}
+#endif
}
diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/ServerInfoDisplay.cs b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/ServerInfoDisplay.cs
index ebc84d8d98..c4025fefc4 100644
--- a/Examples/OverridingScenesAndPrefabs/Assets/Scripts/ServerInfoDisplay.cs
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Scripts/ServerInfoDisplay.cs
@@ -1,4 +1,6 @@
+#if !DEDICATED_SERVER
using Unity.Netcode;
+#endif
using UnityEngine;
using UnityEngine.UI;
@@ -6,7 +8,7 @@ public class ServerInfoDisplay : MonoBehaviour
{
public Text ServerTime;
public Text PlayerCount;
-
+#if !DEDICATED_SERVER
private void OnGUI()
{
if (!NetworkManager.Singleton || !NetworkManager.Singleton.IsListening)
@@ -24,4 +26,5 @@ private void OnGUI()
PlayerCount.text = $"Player Count: {NetworkManager.Singleton.ConnectedClients.Count}";
}
}
+#endif
}
diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Settings.meta b/Examples/OverridingScenesAndPrefabs/Assets/Settings.meta
new file mode 100644
index 0000000000..bf54907342
--- /dev/null
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Settings.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f07d39c4f18773945af7943acf04dff7
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Settings/Build Profiles.meta b/Examples/OverridingScenesAndPrefabs/Assets/Settings/Build Profiles.meta
new file mode 100644
index 0000000000..c47c89da39
--- /dev/null
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Settings/Build Profiles.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 38b8655f79da8bd4ea13982ac8833b71
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Settings/Build Profiles/New Windows Server Profile.asset b/Examples/OverridingScenesAndPrefabs/Assets/Settings/Build Profiles/New Windows Server Profile.asset
new file mode 100644
index 0000000000..b5b4979d3e
--- /dev/null
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Settings/Build Profiles/New Windows Server Profile.asset
@@ -0,0 +1,49 @@
+%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: 15003, guid: 0000000000000000e000000000000000, type: 0}
+ m_Name: New Windows Server Profile
+ m_EditorClassIdentifier:
+ m_AssetVersion: 1
+ m_BuildTarget: 19
+ m_Subtarget: 1
+ m_PlatformId: 8d1e1bca926649cba89d37a4c66e8b3d
+ m_PlatformBuildProfile:
+ rid: 4481205133896843345
+ m_OverrideGlobalSceneList: 0
+ m_Scenes: []
+ m_ScriptingDefines:
+ - DEDICATED_SERVER
+ m_PlayerSettingsYaml:
+ m_Settings: []
+ references:
+ version: 2
+ RefIds:
+ - rid: 4481205133896843345
+ type: {class: WindowsPlatformSettings, ns: UnityEditor.WindowsStandalone, asm: UnityEditor.WindowsStandalone.Extensions}
+ data:
+ m_Development: 0
+ m_ConnectProfiler: 0
+ m_BuildWithDeepProfilingSupport: 0
+ m_AllowDebugging: 0
+ m_WaitForManagedDebugger: 0
+ m_ManagedDebuggerFixedPort: 0
+ m_ExplicitNullChecks: 0
+ m_ExplicitDivideByZeroChecks: 0
+ m_ExplicitArrayBoundsChecks: 0
+ m_CompressionType: 0
+ m_InstallInBuildFolder: 0
+ m_WindowsBuildAndRunDeployTarget: 0
+ m_Architecture: 0
+ m_CreateSolution: 0
+ m_CopyPDBFiles: 0
+ m_WindowsDevicePortalAddress:
+ m_WindowsDevicePortalUsername:
diff --git a/Examples/OverridingScenesAndPrefabs/Assets/Settings/Build Profiles/New Windows Server Profile.asset.meta b/Examples/OverridingScenesAndPrefabs/Assets/Settings/Build Profiles/New Windows Server Profile.asset.meta
new file mode 100644
index 0000000000..6543ae07a8
--- /dev/null
+++ b/Examples/OverridingScenesAndPrefabs/Assets/Settings/Build Profiles/New Windows Server Profile.asset.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ceabbe1f96a84864d8cecdc70db0a1f8
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 11400000
+ userData:
+ assetBundleName:
+ assetBundleVariant: