### Jobified Server Start Method Initialization Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/transport/workflow-client-server-jobs.md Initializes the NetworkDriver and NativeList for connections, and binds the driver to a specific network endpoint and port. This method is unchanged from the simple server example. ```csharp void Start () { m_Connections = new NativeList(16, Allocator.Persistent); m_Driver = new NetworkDriver.Create(); var endpoint = NetworkEndPoint.AnyIpv4; endpoint.Port = 9000; if (m_Driver.Bind(endpoint) != 0) Debug.Log("Failed to bind to port 9000"); else m_Driver.Listen(); } ``` -------------------------------- ### Server Start Method Logic Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/transport/workflow-client-server-udp.md Initializes the NetworkDriver, binds to a port, and starts listening for incoming connections. Also, creates a persistent NativeList to store client connections. ```csharp void Start () { m_Driver = NetworkDriver.Create(); var endpoint = NetworkEndPoint.AnyIpv4; endpoint.Port = 9000; if (m_Driver.Bind(endpoint) != 0) Debug.Log("Failed to bind to port 9000"); else m_Driver.Listen(); m_Connections = new NativeList(16, Allocator.Persistent); } ``` -------------------------------- ### Example Single Command with Log Files (Windows) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/command-line-helper.md An example of running server and client on a single command line in Windows, with custom log file names. ```cmd C:\Users\sarao>HelloWorld\Build\HelloWorld.exe -logfile log-server.txt -mode server & HelloWorld\Build\HelloWorld.exe -logfile log-client.txt -mode client ``` -------------------------------- ### Start Relay Host with Unity Services Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/relay/relay.md Initializes Unity Services, authenticates the user, creates a relay server allocation, and starts a host. Use this to set up the relay server and obtain a join code. ```csharp /// /// Creates a relay server allocation and start a host /// /// The maximum amount of clients that can connect to the relay /// The join code public async Task StartHostWithRelay(int maxConnections=5) { //Initialize the Unity Services engine await UnityServices.InitializeAsync(); //Always authenticate your users beforehand if (!AuthenticationService.Instance.IsSignedIn) { //If not already logged in await AuthenticationService.Instance.SignInAnonymouslyAsync(); } // Request allocation and join code Allocation allocation = await RelayService.Instance.CreateAllocationAsync(maxConnections); var joinCode = await RelayService.Instance.GetJoinCodeAsync(allocation.AllocationId); // Configure transport NetworkManager.Singleton.GetComponent().SetRelayServerData(new RelayServerData(allocation, "dtls")); // Start host return NetworkManager.Singleton.StartHost() ? joinCode : null; } ``` -------------------------------- ### Start NetworkManager as Server, Host, or Client Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/components/networkmanager.md Invoke these methods to start the NetworkManager. Use StartServer() for a dedicated server, StartHost() for a server with a local client, and StartClient() for a standalone client. ```csharp NetworkManager.Singleton.StartServer(); // Starts the NetworkManager as just a server (that is, no local client). NetworkManager.Singleton.StartHost(); // Starts the NetworkManager as both a server and a client (that is, has local client) NetworkManager.Singleton.StartClient(); // Starts the NetworkManager as just a client. ``` -------------------------------- ### Start Network Manager Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/troubleshooting/troubleshooting.md Use these methods to start a server, host, or client. Ensure the NetworkManager component is attached to a GameObject in your scene before calling these. ```csharp NetworkManager.Singleton.StartServer() NetworkManager.Singleton.StartHost() NetworkManager.Singleton.StartClient() ``` -------------------------------- ### NetworkSettings Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/transport/network-settings.md Demonstrates how to create and configure NetworkSettings with a custom disconnect timeout. ```csharp var settings = new NetworkSettings(); settings.WithNetworkConfigParameters(disconnectTimeoutMS: 1000); var driver = NetworkDriver.Create(settings); ``` -------------------------------- ### NetworkObjectPool Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/advanced-topics/object-pooling.md This example demonstrates a NetworkObjectPool used in the Boss Room Sample for managing projectile objects. It initializes pools for prefabs and provides methods to get and return network objects. ```csharp https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop/blob/v2.2.0/Assets/Scripts/Infrastructure/NetworkObjectPool.cs ``` -------------------------------- ### SimpleRpcState Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/networkbehaviour-synchronize.md This example demonstrates how to use NetworkBehaviour.OnSynchronize to synchronize the state of late-joining clients. It also includes an RPC to synchronize state changes for already connected clients. ```csharp using UnityEngine; using Unity.Netcode; /// /// Simple RPC driven state that shows one /// form of NetworkBehaviour.OnSynchronize usage /// public class SimpleRpcState : NetworkBehaviour { private bool m_ToggleState; /// /// Late joining clients will be synchronized /// to the most current m_ToggleState /// protected override void OnSynchronize(ref BufferSerializer serializer) { serializer.SerializeValue(ref m_ToggleState); base.OnSynchronize(ref serializer); } public void ToggleState(bool stateIsSet) { m_ToggleState = stateIsSet; } /// /// Synchronizes connected clients with the /// server-side m_ToggleState /// /// [Rpc(SendTo.ClientsAndHost)] private void ToggleStateClientRpc(bool stateIsSet) { m_ToggleState = stateIsSet; } } ``` -------------------------------- ### Install Packages Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/wiki/Building-Locally Installs project dependencies using Yarn. ```bash yarn install ``` -------------------------------- ### Install Docusaurus (Windows) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/wiki/Building-Locally Installs Docusaurus globally for local development on Windows. ```bash yarn global add docusaurus-init ``` -------------------------------- ### Netcode for GameObjects Connection Approval Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/installation/migratingfromUNet.md Server-only example demonstrating the Connection Approval callback in Netcode for GameObjects. This replaces UNet's OnServerAddPlayer for managing incoming connections and player object creation. ```csharp using Unity.Netcode; private void Setup() { NetworkManager.Singleton.ConnectionApprovalCallback += ApprovalCheck; NetworkManager.Singleton.StartHost(); } private void ApprovalCheck(byte[] connectionData, ulong clientId, NetworkManager.ConnectionApprovedDelegate callback) { //Your logic here bool approve = true; bool createPlayerObject = true; // The Prefab hash. Use null to use the default player prefab // If using this hash, replace "MyPrefabHashGenerator" with the name of a Prefab added to the NetworkPrefabs field of your NetworkManager object in the scene ulong? prefabHash = NetworkpawnManager.GetPrefabHashFromGenerator("MyPrefabHashGenerator"); //If approve is true, the connection gets added. If it's false. The client gets disconnected callback(createPlayerObject, prefabHash, approve, positionToSpawnAt, rotationToSpawnWith); } ``` -------------------------------- ### Install Multiplayer Samples Coop Package Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/learn/bossroom/getting-started-boss-room.md Install the reusable sample scripts package from the Unity multiplayer samples repository using this manifest file entry. ```json "com.unity.multiplayer.samples.coop": "https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop.git?path=/Packages/com.unity.multiplayer.samples.coop" ``` -------------------------------- ### INetworkParameter Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/transport/network-settings.md Shows how to implement the INetworkParameter interface for custom network settings, including validation. ```csharp public struct MyCustomParameter : INetworkParameter { public int MyCustomInt; public float MyCustomFloat; public bool Validate() { if (MyCustomInt <= 0) { UnityEngine.Debug.LogError($"{nameof(MyCustomInt)} value ({MyCustomInt}) must be greater than 0"); return false; } return true; } } ``` -------------------------------- ### Initialize Components for Spawn and Start Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/networkbehaviour.md Use a common initialization method invoked by both Start and OnNetworkSpawn to ensure properties are set for dynamically spawned NetworkObjects. This prevents null reference issues when accessing components in OnNetworkSpawn. ```csharp public class MyNetworkBehaviour : NetworkBehaviour { private MeshRenderer m_MeshRenderer; private void Start() { Initialize(); } private void Initialize() { if (m_MeshRenderer == null) { m_MeshRenderer = FindObjectOfType(); } } public override void OnNetworkSpawn() { Initialize(); // Do things with m_MeshRenderer base.OnNetworkSpawn(); } } ``` -------------------------------- ### Server Scene Loading and Unloading Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/scenemanagement/using-networkscenemanager.md This example demonstrates how a server can subscribe to scene events, load a scene additively, store a reference to the loaded scene, and then unload it. It includes handling scene event types for load completion and unload completion. ```csharp public class ProjectSceneManager : NetworkBehaviour { /// INFO: You can remove the #if UNITY_EDITOR code segment and make SceneName public, /// but this code assures if the scene name changes you won't have to remember to /// manually update it. #if UNITY_EDITOR public UnityEditor.SceneAsset SceneAsset; private void OnValidate() { if (SceneAsset != null) { m_SceneName = SceneAsset.name; } } #endif [SerializeField] private string m_SceneName; private Scene m_LoadedScene; public bool SceneIsLoaded { get { if (m_LoadedScene.IsValid() && m_LoadedScene.isLoaded) { return true; } return false; } } public override void OnNetworkSpawn() { if (IsServer && !string.IsNullOrEmpty(m_SceneName)) { NetworkManager.SceneManager.OnSceneEvent += SceneManager_OnSceneEvent; var status = NetworkManager.SceneManager.LoadScene(m_SceneName, LoadSceneMode.Additive); CheckStatus(status); } base.OnNetworkSpawn(); } private void CheckStatus(SceneEventProgressStatus status, bool isLoading = true) { var sceneEventAction = isLoading ? "load" : "unload"; if (status != SceneEventProgressStatus.Started) { Debug.LogWarning($"Failed to {sceneEventAction} {m_SceneName} with" + $" a {nameof(SceneEventProgressStatus)}: {status}"); } } /// /// Handles processing notifications when subscribed to OnSceneEvent /// /// class that has information about the scene event private void SceneManager_OnSceneEvent(SceneEvent sceneEvent) { var clientOrServer = sceneEvent.ClientId == NetworkManager.ServerClientId ? "server" : "client"; switch (sceneEvent.SceneEventType) { case SceneEventType.LoadComplete: { // We want to handle this for only the server-side if (sceneEvent.ClientId == NetworkManager.ServerClientId) { // *** IMPORTANT *** // Keep track of the loaded scene, you need this to unload it m_LoadedScene = sceneEvent.Scene; } Debug.Log($"Loaded the {sceneEvent.SceneName} scene on " + $"{clientOrServer}-({sceneEvent.ClientId})."); break; } case SceneEventType.UnloadComplete: { Debug.Log($"Unloaded the {sceneEvent.SceneName} scene on " + $"{clientOrServer}-({sceneEvent.ClientId})."); break; } case SceneEventType.LoadEventCompleted: case SceneEventType.UnloadEventCompleted: { var loadUnload = sceneEvent.SceneEventType == SceneEventType.LoadEventCompleted ? "Load" : "Unload"; Debug.Log($"{loadUnload} event completed for the following client " + $"identifiers:({sceneEvent.ClientsThatCompleted})"); if (sceneEvent.ClientsThatTimedOut.Count > 0) { Debug.LogWarning($"{loadUnload} event timed out for the following client " + $"identifiers:({sceneEvent.ClientsThatTimedOut})"); } break; } } } public void UnloadScene() { // Assure only the server calls this when the NetworkObject is // spawned and the scene is loaded. if (!IsServer || !IsSpawned || !m_LoadedScene.IsValid() || !m_LoadedScene.isLoaded) { return; } // Unload the scene var status = NetworkManager.SceneManager.UnloadScene(m_LoadedScene); CheckStatus(status, false); } } ``` -------------------------------- ### NetworkSettings Extension Methods Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/transport/network-settings.md Provides extension methods for NetworkSettings to add and retrieve custom parameters. ```csharp public static class MyCustomParameterExtensions { private const int k_MyCustomIntDefault = 1024; private const float k_MyCustomFloatDefault = 1.0f; public static ref NetworkSettings WithMyCustomParameters( ref this NetworkSettings settings, int myCustomInt = k_MyCustomIntDefault, float myCustomFloat = k_MyCustomFloatDefault ) { var parameter = new MyCustomParameter { MyCustomInt = myCustomInt, myCustomFloat = myCustomFloat, }; settings.AddRawParameterStruct(ref parameter); return ref settings; } public static MyCustomParameter GetMyCustomParameters(ref this NetworkSettings settings) { if (!settings.TryGet(out var parameter)) { parameter.MyCustomInt = k_MyCustomIntDefault; parameter.MyCustomFloat = k_MyCustomFloatDefault; } return parameter; } } ``` -------------------------------- ### Launch Client on Windows Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/command-line-helper.md Use this command to start the HelloWorld executable in client mode on Windows. Replace placeholder text with your project's path. ```cmd \HelloWorld.exe -mode client ``` -------------------------------- ### Launch Server on Windows Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/command-line-helper.md Use this command to start the HelloWorld executable in server mode on Windows. Replace placeholder text with your project's path. ```cmd \HelloWorld.exe -mode server ``` -------------------------------- ### Server Handles Connection Data Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/learn/bitesize/bitesize-dynamicprefabs.md The server listens for the NetworkManager's ConnectionApprovalCallback and defines the behavior to invoke. This example sets up the callback in Start(). ```csharp void Start() { NetworkManager.ConnectionApprovalCallback += ConnectionApprovalCheck; } ``` -------------------------------- ### Subscribe to SceneManager.OnSynchronize Event Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/scenemanagement/scene-events.md Example of subscribing to the NetworkSceneManager.OnSynchronize event on the client side. This is recommended to be done immediately after starting the client to ensure all scene events are captured. ```csharp public bool ConnectPlayer() { var success = NetworkManager.Singleton.StartClient(); if (success) { NetworkManager.Singleton.SceneManager.OnSynchronize += SceneManager_OnSynchronize; } return success; } private void SceneManager_OnSynchronize(ulong clientId) { Debug.Log($ ``` -------------------------------- ### Launch Server and Client on Single Line (Windows) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/command-line-helper.md Execute both the server and client instances of HelloWorld on a single command line in Windows. Ensure placeholder paths are updated. ```cmd \HelloWorld.exe -mode server & \HelloWorld.exe -mode client ``` -------------------------------- ### NetworkVariable Synchronization and Notification Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/networkvariable.md This C# script demonstrates initial NetworkVariable synchronization on spawn and subscribing to OnValueChanged for change notifications. It's intended for a single server/host and single client setup. ```csharp public class TestNetworkVariableSynchronization : NetworkBehaviour { private NetworkVariable m_SomeValue = new NetworkVariable(); private const int k_InitialValue = 1111; public override void OnNetworkSpawn() { if (IsServer) { m_SomeValue.Value = k_InitialValue; NetworkManager.OnClientConnectedCallback += NetworkManager_OnClientConnectedCallback; } else { if (m_SomeValue.Value != k_InitialValue) { Debug.LogWarning($"NetworkVariable was {m_SomeValue.Value} upon being spawned" + $" when it should have been {k_InitialValue}"); } else { Debug.Log($"NetworkVariable is {m_SomeValue.Value} when spawned."); } m_SomeValue.OnValueChanged += OnSomeValueChanged; } } private void NetworkManager_OnClientConnectedCallback(ulong obj) { StartCoroutine(StartChangingNetworkVariable()); } private void OnSomeValueChanged(int previous, int current) { Debug.Log($"Detected NetworkVariable Change: Previous: {previous} | Current: {current}"); } private IEnumerator StartChangingNetworkVariable() { var count = 0; var updateFrequency = new WaitForSeconds(0.5f); while (count < 4) { m_SomeValue.Value += m_SomeValue.Value; yield return updateFrequency; } NetworkManager.OnClientConnectedCallback -= NetworkManager_OnClientConnectedCallback; } } ``` -------------------------------- ### Install Docusaurus (Mac) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/wiki/Building-Locally Installs Docusaurus and initializes a temporary project for local development on macOS. ```bash npx @docusaurus/init@latest init temp classic ``` -------------------------------- ### Update Script References (Installer Version) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/installation/migratingfrommlapi.md Use the MLAPI Patcher to update script references when migrating from the installer version of MLAPI. ```bash Installer Update Script References ``` -------------------------------- ### Launch Client on macOS Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/command-line-helper.md Use this command to start the HelloWorld executable in client mode on macOS. Replace placeholders with your project's path and name. ```shell /HelloWorld.app/Contents/MacOS/ -mode client -logfile - ``` -------------------------------- ### Launch Server and Client on Single Line (macOS) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/command-line-helper.md Execute both the server and client instances of HelloWorld on a single command line in macOS. Ensure placeholders are updated. ```shell /HelloWorld.app/Contents/MacOS/ -mode server -logfile - & HelloWorld.app/Contents/MacOS/ -mode client -logfile - ``` -------------------------------- ### JobifiedClientBehaviour Start Method Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/transport/workflow-client-server-jobs.md Initializes the NetworkDriver and NativeArrays for connection and completion status in the Start method. It then establishes a connection to the server endpoint. ```csharp void Start () { m_Driver = NetworkDriver.Create(); m_Connection = new NativeArray(1, Allocator.Persistent); m_Done = new NativeArray(1, Allocator.Persistent); var endpoint = NetworkEndPoint.LoopbackIpv4; endpoint.Port = 9000; m_Connection[0] = m_Driver.Connect(endpoint); } ``` -------------------------------- ### Launch Server on macOS Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/command-line-helper.md Use this command to start the HelloWorld executable in server mode on macOS. Replace placeholders with your project's path and name. ```shell /HelloWorld.app/Contents/MacOS/ -mode server -logfile - ``` -------------------------------- ### Start Game Countdown Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/learn/bitesize/bitesize-invaders.md Initiates the game timer and sends the initial time remaining to clients. This is called once to signal the start of the game. ```csharp if (!IsServer) return; if (ShouldStartCountDown) { m_GameStartTime = Time.time; m_TimeRemaining = m_GameDuration; RPC_SendTimeRemaining(m_TimeRemaining); ShouldStartCountDown = false; } ``` -------------------------------- ### Use InstantiateAndSpawn for Simplified Spawning Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/object-spawning.md Leverage the `NetworkSpawnManager.InstantiateAndSpawn` method to automatically handle the instantiation and spawning of a network prefab, including whether to spawn an override. This is useful when you want a more streamlined spawning process. ```csharp var networkObject = NetworkManager.SpawnManager.InstantiateAndSpawn(myPrefab, ownerId); ``` -------------------------------- ### NetworkVariable Permissions Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/networkvariable.md Demonstrates various NetworkVariable permission configurations for tracking player states. Each variable includes comments explaining its purpose and permission rationale. ```csharp public class PlayerState : NetworkBehaviour { private const float k_DefaultHealth = 100.0f; /// /// Default Permissions: Everyone can read, server can only write /// Player health is typically something determined (updated/written to) on the server /// side, but a value everyone should be synchronized with (that is, read permissions). /// public NetworkVariable Health = new NetworkVariable(k_DefaultHealth); /// /// Owner Read Permissions: Owner or server can read /// Owner Write Permissions: Only the Owner can write /// A player's ammo count is something that you might want, for convenience sake, the /// client-side to update locally. This might be because you are trying to reduce /// bandwidth consumption for the server and all non-owners/ players or you might be /// trying to incorporate a more client-side "hack resistant" design where non-owners /// are never synchronized with this value. /// public NetworkVariable AmmoCount = new NetworkVariable(default, NetworkVariableReadPermission.Owner, NetworkVariableWritePermission.Owner); /// /// Owner Write & Everyone Read Permissions: /// A player's model's skin selection index. You might have the option to allow players /// to select different skin materials as a way to further encourage a player's personal /// association with their player character. It would make sense to make the permissions /// setting of the NetworkVariable such that the client can change the value, but everyone /// will be notified when it changes to visually reflect the new skin selection. /// public NetworkVariable SkinSelectionIndex = new NetworkVariable(default, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner); /// /// Owner Read & Server Write Permissions: /// You might incorporate some form of reconnection logic that stores a player's state on /// the server side and can be used by the client to reconnect a player if disconnected /// unexpectedly. In order for the client to let the server know it's the "same client" /// you might have implemented a keyed array (that is, Hashtable, Dictionary, etc, ) to track /// each connected client. The key value for each connected client would only be written to /// the each client's PlayerState.ReconnectionKey. Under this scenario, you only want the /// server to have write permissions and the owner (client) to be synchronized with this /// value (via owner only read permissions). /// public NetworkVariable ReconnectionKey = new NetworkVariable(default, NetworkVariableReadPermission.Owner, NetworkVariableWritePermission.Server); } ``` -------------------------------- ### Load Dynamic Prefabs by GUID Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/learn/bitesize/bitesize-dynamicprefabs.md This code snippet shows how a client loads necessary dynamic prefabs using their GUIDs before retrying the connection. ```csharp yield return Addressables.LoadAssetsAsync(prefabGUIDs, null); yield return SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().name, LoadSceneMode.Additive); yield return null; NetworkManager.StartClient(); ``` -------------------------------- ### Send Prefab GUIDs for Client Preloading Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/learn/bitesize/bitesize-dynamicprefabs.md When a client has a mismatching prefab hash, this code sends a payload containing the GUIDs of dynamic prefabs the client needs to load. ```csharp NetworkManager.ConnectionApproval.SetDenied(request, "Client needs to preload prefabs", System.Text.Json.JsonSerializer.Serialize(new DisconnectReasonPayload { Reason = DisconnectReason.ClientNeedsToPreload, PrefabGUIDs = GetPrefabGUIDsToLoad() })); ``` -------------------------------- ### Launch Server with Log File (Windows) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/command-line-helper.md Modify the server command to output logs to a specific file named 'log-server.txt' in Windows. ```cmd \HelloWorld.exe -logfile log-server.txt -mode server ``` -------------------------------- ### InstantiateAndSpawn with Custom Parameters Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/object-spawning.md Utilize the `InstantiateAndSpawn` method with optional parameters to gain finer control over the spawning process, such as specifying the owner, position, rotation, and override behavior. ```csharp InstantiateAndSpawn(NetworkObject networkPrefab, ulong ownerClientId = NetworkManager.ServerClientId, bool destroyWithScene = false, bool isPlayerObject = false, bool forceOverride = false, Vector3 position = default, Quaternion rotation = default) ``` -------------------------------- ### Single Pooled Dynamic Spawner Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/object-spawning.md This script demonstrates how to implement pooled dynamic spawning for a single network object by using the INetworkPrefabInstanceHandler interface. It keeps a reference to a prefab instance, disabling it when despawned and reactivating it when needed, thus avoiding destruction and reallocation costs. ```csharp public class SinglePooledDynamicSpawner : NetworkBehaviour, INetworkPrefabInstanceHandler { public GameObject PrefabToSpawn; public bool SpawnPrefabAutomatically; private GameObject m_PrefabInstance; private NetworkObject m_SpawnedNetworkObject; private void Start() { // Instantiate our instance when we start (for both clients and server) m_PrefabInstance = Instantiate(PrefabToSpawn); // Get the NetworkObject component assigned to the Prefab instance m_SpawnedNetworkObject = m_PrefabInstance.GetComponent(); // Set it to be inactive m_PrefabInstance.SetActive(false); } private IEnumerator DespawnTimer() { yield return new WaitForSeconds(2); m_SpawnedNetworkObject.Despawn(); StartCoroutine(SpawnTimer()); yield break; } private IEnumerator SpawnTimer() { yield return new WaitForSeconds(2); SpawnInstance(); yield break; } /// /// Invoked only on clients and not server or host /// INetworkPrefabInstanceHandler.Instantiate implementation /// Called when Netcode for GameObjects need an instance to be spawned /// public NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation) { m_PrefabInstance.SetActive(true); m_PrefabInstance.transform.position = transform.position; m_PrefabInstance.transform.rotation = transform.rotation; return m_SpawnedNetworkObject; } /// /// Client and Server side /// INetworkPrefabInstanceHandler.Destroy implementation /// public void Destroy(NetworkObject networkObject) { m_PrefabInstance.SetActive(false); } public void SpawnInstance() { if (!IsServer) { return; } if (m_PrefabInstance != null && m_SpawnedNetworkObject != null && !m_SpawnedNetworkObject.IsSpawned) { m_PrefabInstance.SetActive(true); m_SpawnedNetworkObject.Spawn(); StartCoroutine(DespawnTimer()); } } public override void OnNetworkSpawn() { // We register our network Prefab and this NetworkBehaviour that implements the // INetworkPrefabInstanceHandler interface with the Prefab handler NetworkManager.PrefabHandler.AddHandler(PrefabToSpawn, this); if (!IsServer || !SpawnPrefabAutomatically) { return; } if (SpawnPrefabAutomatically) { SpawnInstance(); } } public override void OnNetworkDespawn() { if (m_SpawnedNetworkObject != null && m_SpawnedNetworkObject.IsSpawned) { m_SpawnedNetworkObject.Despawn(); } base.OnNetworkDespawn(); } public override void OnDestroy() { // This example destroys the if (m_PrefabInstance != null) { // Always deregister the prefab NetworkManager.Singleton.PrefabHandler.RemoveHandler(PrefabToSpawn); Destroy(m_PrefabInstance); } base.OnDestroy(); } } ``` -------------------------------- ### Client-Driven Input Sender Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/learn/dealing-with-latency.md This script demonstrates how client input can be sent to the server. It's useful for actions where immediate client feedback is desired and server correction is not critical. ```csharp using Unity.Netcode; using UnityEngine; public class ClientInputSender : NetworkBehaviour { public override void OnNetworkSpawn() { if (!IsOwner) { enabled = false; } } void Update() { if (Input.GetKeyDown(KeyCode.Space)) { PerformAction(); } } void PerformAction() { // In a real scenario, this would send a network message to the server // For demonstration, we'll just log it. Debug.Log("Client performing action..."); // Example: SendInputToServerRpc(); } // Example RPC (Remote Procedure Call) to send input to the server // [ServerRpc] // void SendInputToServerRpc(ServerRpcParams rpcParams = default) // { // // Server-side logic to handle the input // Debug.Log($"Server received input from client {rpcParams.Receive.SenderGlobalObjectIdString}"); // } } ``` -------------------------------- ### Start In-Scene NetworkObject in Despawned State Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/scenemanagement/inscene-placed-networkobjects.md This snippet shows how to configure an in-scene NetworkObject to start in a despawned state by overriding OnNetworkSpawn and conditionally calling Despawn. This logic is server-side only and can be controlled via an inspector property. ```csharp using UnityEngine; using Unity.Netcode; public class MyInSceneNetworkObjectBehaviour : NetworkBehaviour { public bool StartDespawned; private bool m_HasStartedDespawned; public override void OnNetworkSpawn() { if (IsServer && StartDespawned && !m_HasStartedDespawned) { m_HasStartedDespawned = true; NetworkObject.Despawn(false); } base.OnNetworkSpawn(); } public override void OnNetworkDespawn() { gameObject.SetActive(false); base.OnNetworkDespawn(); } public void Spawn(bool destroyWithScene) { if (IsServer && !IsSpawned) { gameObject.SetActive(true); NetworkObject.Spawn(destroyWithScene); } } } ``` -------------------------------- ### Start Network Manager Modes (Host, Client, Server) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/get-started-with-ngo.md Provides buttons to initiate the Host, Client, or Server connection modes for the NetworkManager. Used within the OnGUI method. ```csharp private void StartButtons() { if (GUILayout.Button("Host")) m_NetworkManager.StartHost(); if (GUILayout.Button("Client")) m_NetworkManager.StartClient(); if (GUILayout.Button("Server")) m_NetworkManager.StartServer(); } ``` -------------------------------- ### Distributed Authority Spawning Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/spawning-synchronization.md Illustrates spawning a projectile directly without explicit server RPCs, suitable for scenarios where the spawning logic can be executed on any peer with authority. This example assumes the `NetworkBehaviour` has the necessary authority. ```csharp /// /// Pseudo player weapon that is assumed to be /// attached to a fixed child node of the player. /// (i.e. like a hand node or the like) /// public class PlayerWeapon : NetworkBehaviour { // For example purposes, the projectile to spawn public GameObject Projectile; // For example purposes, an offset from the weapon // to spawn the projectile. public GameObject WeaponFiringOffset; public void FireWeapon() { var instance = Instantiate(Projectile); var instanceNetworkObject = instance.GetComponent(); instance.transform.position = WeaponFiringOffset.transform.position; instance.transform.forward = transform.forward; instanceNetworkObject.Spawn(); } } ``` -------------------------------- ### ExplosionFx Script for Deferred Despawning Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/basics/deferred-despawning.md This script controls the particle system for an explosion effect. The authority starts the particle system locally upon spawning, while non-authority instances start it when their associated projectile is despawned after a deferred despawn. ```csharp public class ExplosionFx : NetworkBehaviour { public ParticleSystem ParticleSystem; private void OnEnable() { // In the event a pool is used, it is always good to // make sure the particle system is not playing SetParticlePlayingState(); } public override void OnNetworkSpawn() { // Authority starts the particle system (locally) when spawned if (HasAuthority) { SetParticlePlayingState(true); } base.OnNetworkSpawn(); } /// /// Used to start/stop the particle system /// Non-Authority starts this when its associated projectile /// is finally despawned /// public void SetParticlePlayingState(bool isPlaying = false) { if (ParticleSystem) { if(isPlaying) { ParticleSystem.Play(); } else { ParticleSystem.Stop(); } } } } ``` -------------------------------- ### UNET RPC Example Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/installation/migratingfromUNet.md Illustrates how to define and invoke server commands and client RPCs in UNet. Requires inheriting from NetworkBehaviour. ```csharp public class MyUnetClass : NetworkBehaviour { [SyncVar] public float MySyncFloat; public void Start() { if (isClient) { CmdExample(10f); } else if (isServer) { RpcExample(10f); } } [Command] public void CmdExample(float x) { Debug.Log(“Runs on server”); } [ClientRpc] public void RpcExample(float x) { Debug.Log(“Runs on clients”); } } ``` -------------------------------- ### Launch Client with Log File (Windows) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/tutorials/command-line-helper.md Modify the client command to output logs to a specific file named 'log-client.txt' in Windows. ```cmd \HelloWorld.exe -logfile log-client.txt -mode client ``` -------------------------------- ### Replace NetworkServer.Spawn with NetworkObject.Spawn (Netcode for GameObjects) Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/installation/migratingfromUNet.md This Netcode for GameObjects snippet shows how to instantiate a prefab and then spawn it on the network using the NetworkObject.Spawn method. ```csharp GameObject go = Instantiate(myPrefab, Vector3.zero, Quaternion.identity); go.GetComponent().Spawn(); ``` -------------------------------- ### Change Scene in UNet Source: https://github.com/unity-technologies/com.unity.multiplayer.docs/blob/main/docs/installation/migratingfromUNet.md Example of changing scenes using the NetworkManager in UNet. ```csharp public void ChangeScene() { MyNetworkManager.ServerChangeScene("MyNewScene"); } ```