Skip to content

Commit 1249843

Browse files
chore: update example overriding scenes networkprefabs dedicated server (#3207)
* update Adding support for a dedicated server build. * update adding windows dedicated server build example with DEDICATED_SERVER define
1 parent 248aa21 commit 1249843

10 files changed

+293
-14
lines changed

Examples/OverridingScenesAndPrefabs/Assets/Scripts/MoverScriptNoRigidbody.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ protected override void OnNetworkPostSpawn()
174174
}
175175

176176
m_ParentedText?.gameObject.SetActive(true);
177+
#if !DEDICATED_SERVER
177178
UpdateParentedText();
179+
#endif
178180
base.OnNetworkPostSpawn();
179181
}
180182

@@ -201,7 +203,9 @@ public override void OnNetworkObjectParentChanged(NetworkObject parentNetworkObj
201203
{
202204
Debug.Log($"Parented under {parentNetworkObject.name}");
203205
}
206+
#if !DEDICATED_SERVER
204207
UpdateParentedText();
208+
#endif
205209
base.OnNetworkObjectParentChanged(parentNetworkObject);
206210
}
207211

@@ -334,6 +338,7 @@ private void ApplyInput()
334338
m_PlayerBallMotion.HasMotion(moveMotion);
335339
}
336340

341+
#if !DEDICATED_SERVER
337342
/// <summary>
338343
/// Updates player TextMesh relative to each client's camera view
339344
/// </summary>
@@ -373,4 +378,5 @@ private void UpdateParentedText()
373378
}
374379
}
375380
}
381+
#endif
376382
}

Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkManagerBootstrapper.cs

Lines changed: 197 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
1+
#if !DEDICATED_SERVER || (DEDICATED_SERVER && !UNITY_EDITOR)
12
using System;
3+
#endif
24
using System.Collections.Generic;
35
using System.Linq;
6+
#if !DEDICATED_SERVER
47
using System.Threading.Tasks;
8+
#endif
59
using Unity.Netcode;
10+
#if !DEDICATED_SERVER
611
using Unity.Services.Authentication;
712
using Unity.Services.Core;
813
using Unity.Services.Multiplayer;
14+
#else
15+
using Unity.Netcode.Transports.UTP;
16+
#endif
917
using UnityEngine;
18+
#if !DEDICATED_SERVER
1019
using SessionState = Unity.Services.Multiplayer.SessionState;
20+
#endif
1121

1222
#region NetworkManagerBootstrapperEditor
1323
#if UNITY_EDITOR
@@ -67,7 +77,7 @@ protected override void OnValidateComponent()
6777
base.OnValidateComponent();
6878
}
6979
#endif
70-
#endregion
80+
#endregion
7181

7282
#region Properties
7383
public static NetworkManagerBootstrapper Instance;
@@ -98,12 +108,13 @@ private enum ConnectionStates
98108

99109
[SerializeField]
100110
private bool m_ServicesRegistered;
111+
#if !DEDICATED_SERVER
101112
private ISession m_CurrentSession;
102113
private string m_SessionName;
103114
private string m_ProfileName;
104115
private Task m_SessionTask;
105-
106-
#endregion
116+
#endif
117+
#endregion
107118

108119
#region Initialization and Destroy
109120
public static string GetRandomString(int length)
@@ -120,12 +131,27 @@ public void SetFrameRate(int targetFrameRate, bool enableVsync)
120131

121132
private void Awake()
122133
{
134+
#if !DEDICATED_SERVER
123135
Screen.SetResolution((int)(Screen.currentResolution.width * 0.40f), (int)(Screen.currentResolution.height * 0.40f), FullScreenMode.Windowed);
124136
SetFrameRate(TargetFrameRate, EnableVSync);
137+
#endif
125138
SetSingleton();
126139
m_SceneBootstrapLoader = GetComponent<SceneBootstrapLoader>();
127140
}
128141

142+
#if DEDICATED_SERVER
143+
private void Start()
144+
{
145+
m_SceneBootstrapLoader.OnMainMenuLoaded += OnMainMenuLoaded;
146+
m_SceneBootstrapLoader.LoadMainMenu();
147+
}
148+
149+
private void OnMainMenuLoaded()
150+
{
151+
m_SceneBootstrapLoader.OnMainMenuLoaded -= OnMainMenuLoaded;
152+
StartDedicatedServer();
153+
}
154+
#else
129155
private async void Start()
130156
{
131157
OnClientConnectedCallback += OnClientConnected;
@@ -152,17 +178,20 @@ private async void Start()
152178
}
153179
}
154180
m_SceneBootstrapLoader.LoadMainMenu();
155-
}
156181

182+
}
157183
private void OnDestroy()
158184
{
159185
OnClientConnectedCallback -= OnClientConnected;
160186
OnClientDisconnectCallback -= OnClientDisconnect;
161187
OnConnectionEvent -= OnClientConnectionEvent;
162188
}
163-
#endregion
189+
#endif
190+
#endregion
164191

165192
#region Session and Connection Event Handling
193+
194+
#if !DEDICATED_SERVER
166195
private void OnClientConnectionEvent(NetworkManager networkManager, ConnectionEventData eventData)
167196
{
168197
LogMessage($"[{Time.realtimeSinceStartup}] Connection event {eventData.EventType} for Client-{eventData.ClientId}.");
@@ -235,9 +264,11 @@ private async Task<ISession> ConnectThroughLiveService()
235264
}
236265
return null;
237266
}
238-
#endregion
267+
#endif
268+
#endregion
239269

240270
#region GUI Menu
271+
#if !DEDICATED_SERVER
241272
public void StartOrConnectToDistributedAuthoritySession()
242273
{
243274
m_SessionTask = ConnectThroughLiveService();
@@ -364,9 +395,11 @@ private void OnGUI()
364395
}
365396
GUILayout.EndArea();
366397
}
367-
#endregion
398+
#endif
399+
#endregion
368400

369401
#region Server Camera Handling
402+
#if !DEDICATED_SERVER
370403
private Vector3 m_CameraOriginalPosition;
371404
private Quaternion m_CameraOriginalRotation;
372405
private int m_CurrentFollowPlayerIndex = -1;
@@ -438,9 +471,159 @@ public void ClearFollowPlayer()
438471
SetCameraDefaults();
439472
}
440473
}
441-
#endregion
474+
#endif
475+
#endregion
442476

443477
#region Update Methods and Properties
478+
#if DEDICATED_SERVER
479+
private UnityTransport m_UnityTransport;
480+
/// <summary>
481+
/// All of the dedicated server specific script logic is contained and only compiled when DEDICATED_SERVER is defined
482+
/// </summary>
483+
484+
private void StartDedicatedServer()
485+
{
486+
m_UnityTransport = NetworkConfig.NetworkTransport as UnityTransport;
487+
if (m_UnityTransport != null)
488+
{
489+
// Always good to know what scenes are currently loaded since you might have
490+
// different scenes to load for a DGS vs client
491+
var scenesPreloaded = new System.Text.StringBuilder();
492+
scenesPreloaded.Append("Scenes Preloaded: ");
493+
for (int i = 0; i < UnityEngine.SceneManagement.SceneManager.sceneCount; i++)
494+
{
495+
var scene = UnityEngine.SceneManagement.SceneManager.GetSceneAt(i);
496+
scenesPreloaded.Append($"[{scene.name}]");
497+
}
498+
Debug.Log(scenesPreloaded.ToString());
499+
500+
// Set the application frame rate to like 30 to reduce frame processing overhead
501+
Application.targetFrameRate = 30;
502+
503+
Debug.Log($"[Pre-Init] Server Address Endpoint: {m_UnityTransport.ConnectionData.ServerEndPoint}");
504+
Debug.Log($"[Pre-Init] Server Listen Endpoint: {m_UnityTransport.ConnectionData.ListenEndPoint}");
505+
// Setup your IP and port sepcific to your DGS
506+
//unityTransport.SetConnectionData(ListenAddress, ListenPort, ListenAddress);
507+
508+
//Debug.Log($"[Post-Init] Server Address Endpoint: {unityTransport.ConnectionData.ServerEndPoint}");
509+
//Debug.Log($"[Post-Init] Server Listen Endpoint: {unityTransport.ConnectionData.ListenEndPoint}");
510+
511+
// Get the server started notification
512+
OnServerStarted += ServerStarted;
513+
514+
// Start the server listening
515+
m_SceneBootstrapLoader.StartSession(SceneBootstrapLoader.StartAsTypes.Server);
516+
}
517+
else
518+
{
519+
Debug.LogError("Failed to get the UnityTransport!");
520+
}
521+
}
522+
523+
/// <summary>
524+
/// Register callbacks when the OnServerStarted callback is invoked.
525+
/// This makes it easier to know you are registering for events only
526+
/// when the server successfully has started.
527+
/// </summary>
528+
private void ServerStarted()
529+
{
530+
Debug.Log("Dedicated Server Started!");
531+
Debug.Log($"[Started] Server Address Endpoint: {m_UnityTransport.ConnectionData.ServerEndPoint}");
532+
Debug.Log($"[Started] Server Listen Endpoint: {m_UnityTransport.ConnectionData.ListenEndPoint}");
533+
Debug.Log("===============================================================");
534+
Debug.Log("[X] Exits session (Shutdown) | [ESC] Exits application instance");
535+
Debug.Log("===============================================================");
536+
OnServerStarted -= ServerStarted;
537+
OnClientConnectedCallback += ClientConnectedCallback;
538+
OnClientDisconnectCallback += ClientDisconnectCallback;
539+
// Register for OnServerStopped
540+
OnServerStopped += ServerStopped;
541+
}
542+
543+
private void ServerStopped(bool obj)
544+
{
545+
OnClientConnectedCallback -= ClientConnectedCallback;
546+
OnClientDisconnectCallback -= ClientDisconnectCallback;
547+
OnServerStopped -= ServerStopped;
548+
Debug.Log("Dedicated Server Stopped!");
549+
Debug.Log("===============================================================");
550+
Debug.Log("[S] Starts new session (StartServer) | [ESC] Exits application");
551+
Debug.Log("===============================================================");
552+
}
553+
554+
private void ClientConnectedCallback(ulong clientId)
555+
{
556+
Debug.Log($"Client-{clientId} connected and approved.");
557+
}
558+
559+
private void ClientDisconnectCallback(ulong clientId)
560+
{
561+
Debug.Log($"Client-{clientId} disconnected.");
562+
}
563+
564+
#if UNITY_EDITOR
565+
private void HandleEditorKeyCommands()
566+
{
567+
// Shutdown/Stop the server
568+
if (Input.GetKeyDown(KeyCode.X) && IsListening && !ShutdownInProgress)
569+
{
570+
Shutdown();
571+
}
572+
else // Start the server (this example makes it automatically start when the application first starts)
573+
if (Input.GetKeyDown(KeyCode.S) && !IsListening)
574+
{
575+
StartDedicatedServer();
576+
}
577+
}
578+
#else
579+
private void HandleConsoleKeyCommands()
580+
{
581+
if (Console.KeyAvailable)
582+
{
583+
var networkManager = NetworkManager.Singleton;
584+
var keyPressed = Console.ReadKey(true);
585+
switch(keyPressed.Key)
586+
{
587+
case ConsoleKey.X:
588+
{
589+
if(networkManager.IsListening && !networkManager.ShutdownInProgress)
590+
{
591+
networkManager.Shutdown();
592+
}
593+
break;
594+
}
595+
case ConsoleKey.S:
596+
{
597+
if (!networkManager.IsListening && !networkManager.ShutdownInProgress)
598+
{
599+
StartDedicatedServer();
600+
}
601+
break;
602+
}
603+
case ConsoleKey.Escape:
604+
{
605+
Application.Quit();
606+
break;
607+
}
608+
}
609+
}
610+
}
611+
#endif
612+
613+
/// <summary>
614+
/// Update that is only included in the build and invoked when running as a dedicated server
615+
/// </summary>
616+
private void DedicatedServerUpdate()
617+
{
618+
#if UNITY_EDITOR
619+
HandleEditorKeyCommands();
620+
#else
621+
HandleConsoleKeyCommands();
622+
#endif
623+
}
624+
625+
#else // End of DEDICATED_SERVER defined region
626+
444627
/// <summary>
445628
/// General update for server-side
446629
/// </summary>
@@ -459,9 +642,13 @@ private void ClientSideUpdate()
459642
{
460643

461644
}
645+
#endif
462646

463647
private void Update()
464648
{
649+
#if DEDICATED_SERVER
650+
DedicatedServerUpdate();
651+
#else
465652
if (IsListening)
466653
{
467654
if (IsServer)
@@ -473,6 +660,7 @@ private void Update()
473660
ClientSideUpdate();
474661
}
475662
}
663+
#endif
476664

477665
if (m_MessageLogs.Count == 0)
478666
{
@@ -487,6 +675,7 @@ private void Update()
487675
}
488676
}
489677
}
678+
490679
#endregion
491680

492681
#region Message Logging

Examples/OverridingScenesAndPrefabs/Assets/Scripts/NetworkPrefabOverrideHandler.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,15 @@ public NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaterni
5252

5353
public void Destroy(NetworkObject networkObject)
5454
{
55+
#if !DEDICATED_SERVER
5556
// Another useful thing about handling this instantiation and destruction of a NetworkObject is that you can do house cleaning
5657
// prior to the object being destroyed. This handles the scenario where the server is following a player and the player disconnects.
5758
// Before destroying the player object, we want to unparent the camera and reset the player being followed.
5859
if (m_NetworkManager.IsServer && !m_NetworkManager.IsHost && Camera.main != null && Camera.main.transform.parent == networkObject.transform)
5960
{
6061
m_NetworkManager.ClearFollowPlayer();
6162
}
63+
#endif
6264
Destroy(networkObject.gameObject);
6365
}
6466
}

0 commit comments

Comments
 (0)