|
| 1 | +--- |
| 2 | +id: mppm |
| 3 | +title: Multiplayer Play Mode |
| 4 | +sidebar_label: Multiplayer Play Mode |
| 5 | +--- |
| 6 | + |
| 7 | +Multiplayer Play Mode (MPPM) enables you to test multiplayer functionality without leaving the Unity Editor. You can simulate up to four Players (the Main Editor Player plus three Virtual Players) simultaneously on the same development device while using the same source assets on disk. You can leverage MPPM to create multiplayer development workflows that reduce the time it takes to build a project, run it locally, and test the server-client relationship. |
| 8 | + |
| 9 | +This document uses the following terminology to distinguish between the primary Unity Editor project and the Virtual Player instances: |
| 10 | + |
| 11 | +- The **Main Editor** refers to the primary (or original) instance of the project in the Unity Editor, and this is the only instance with full authoring capabilities. |
| 12 | +- **Virtual Players** refers to simulated Players created with Multiplayer Play Mode that open in a separate window with limited authoring capabilities when you enter **[Play mode](https://docs.unity3d.com/Manual/GameView.html)**. |
| 13 | +- **Players** refers to all Player instances, including the Main Editor Player and all Virtual Players. |
| 14 | + |
| 15 | +## Requirements |
| 16 | + |
| 17 | +You must meet the following requirements to use Multiplayer Play Mode: |
| 18 | + |
| 19 | +- Install Unity Editor version 2023.1 or later |
| 20 | +- Install the `com.unity.multiplayer.playmode` package (version 0.1.0 or later) |
| 21 | + |
| 22 | +### Limitations |
| 23 | + |
| 24 | +MPPM has some inherent technical limitations, specifically around [scale](#scale) and [authoring](#authoring). |
| 25 | + |
| 26 | +#### Scale |
| 27 | + |
| 28 | +The Unity Editor (and Virtual Player instances) require a lot of system resources; as a result, you shouldn’t use MPPM at scale. It’s designed for use in small-scale, local testing environments. By default, MPPM supports up to four Players (the Main Editor plus three Virtual Players). |
| 29 | + |
| 30 | +#### Authoring |
| 31 | + |
| 32 | +Virtual Player instances open in a Unity Editor window when you enter Play mode. These instances have restricted authoring capabilities because they’re intended as a vehicle to open multiple project runtimes, not to offer multi-editor authoring workflows. |
| 33 | + |
| 34 | +You should use the Main Editor to make changes and the Virtual Players to test multiplayer functionality. This way, you can continue to use existing Editor workflows without learning how to use the Unity Editor in new ways. |
| 35 | + |
| 36 | +You can't access any functionality of the Main Editor from Virtual Players. |
| 37 | + |
| 38 | +### Performance impact |
| 39 | + |
| 40 | +Each Virtual Player increases the demand for system resources. MPPM limits the performance impact of Virtual Players by sharing specific resources, such as the artifact database and imports, between the Main Editor and each Virtual Player. |
| 41 | + |
| 42 | +## Getting started |
| 43 | + |
| 44 | +You can access MPPM by opening the Multiplayer Play Mode window: Select **Window** > **Multiplayer Play Mode**. |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | +The Multiplayer Play Mode window allows you to access Virtual Players and Player Tags. |
| 49 | + |
| 50 | +## Players |
| 51 | + |
| 52 | +Players represent either the Main Editor Player or the Virtual Players that you can enable and disable with the checkbox next to the Virtual Player name (from the Multiplayer Play Mode window). There are four available Player slots: |
| 53 | + |
| 54 | +- Player 1 (The Main Editor) |
| 55 | +- Player 2 (Virtual Player) |
| 56 | +- Player 3 (Virtual Player) |
| 57 | +- Player 4 (Virtual Player) |
| 58 | + |
| 59 | +### Enable a Virtual Player |
| 60 | + |
| 61 | +You can enable up to four Players simultaneously (the Main Editor Player plus three Virtual Players). Note that you must activate Virtual Players before entering **Play mode**. |
| 62 | + |
| 63 | +To enable a Virtual Player: |
| 64 | + |
| 65 | +1. Select the checkbox next to the Virtual Player name (for example, Player 2). |
| 66 | + |
| 67 | + |
| 68 | + |
| 69 | +2. Wait for Unity to activate the Virtual Player. |
| 70 | +3. After the Player is activated, the status changes from **Activating** to **Active**, and you can use the Virtual Player in testing. |
| 71 | + |
| 72 | + |
| 73 | + |
| 74 | +4. Select the **Play** button in the Main Editor. |
| 75 | + |
| 76 | +A Unity Editor Play Mode window should open for each enabled Player (with the window titled after the Player name). |
| 77 | + |
| 78 | +## Player Tags |
| 79 | + |
| 80 | +You can think of Player Tags like launch arguments for Players (the Main Editor Player and Virtual Players). You can configure Player Tags to do things such as: |
| 81 | + |
| 82 | +- Configure a Player to run as a client, server, or host automatically. |
| 83 | +- Configure a Player to automatically run as a member of a specific team (for example, “Red Team” or “Blue Team”). |
| 84 | +- Configure a Player to move faster or slower. |
| 85 | + |
| 86 | +### Attach a Player Tag to a Player |
| 87 | + |
| 88 | +You can attach a Player Tag to a Player by selecting the Player Tag from the Tag drop-down list. In the following example, a single Player Tag (named "Fast") configures a Virtual Player to allow the Player to move faster than the other Players. |
| 89 | + |
| 90 | +:::warning |
| 91 | +You can't attach a Player Tag to an active Player. You must first disable the Player, then attach the Player Tag. |
| 92 | +::: |
| 93 | + |
| 94 | +1. Select the Player Tag from the **Tag** drop-down for the Player. |
| 95 | + |
| 96 | + |
| 97 | + |
| 98 | +2. Enable the Player by selecting the checkbox to its left. |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | +### Add a Player Tag |
| 103 | + |
| 104 | +You can add a Player Tag through the Multiplayer Play Mode window. When you add a Player Tag, it’s automatically added to the `VirtualProjectsConfig.json` file in the `ProjectsSettings` folder. |
| 105 | + |
| 106 | +1. Select the **+** symbol under Player Tags. |
| 107 | + |
| 108 | + |
| 109 | + |
| 110 | +2. Name the Player Tag. |
| 111 | + |
| 112 | + |
| 113 | + |
| 114 | +3. Select **Save**. |
| 115 | + |
| 116 | +You should now see the new Player Tag listed under Player Tags and in the drop-down menu for the Tag option of each Player. |
| 117 | + |
| 118 | + |
| 119 | + |
| 120 | +### Configuring Player Tags |
| 121 | + |
| 122 | +Alone, Player Tags don’t do much at all. You have to target the Player Tag in your game scripts with `CurrentPlayer.Tag`. See the following Player Tag examples: |
| 123 | + |
| 124 | +- [Run as a server, client, or host](#run-as-a-server-client-or-host) |
| 125 | +- [Automatically assign to team](#automatically-assign-to-team) |
| 126 | +- [Simulate network conditions](#simulate-network-conditions) |
| 127 | + |
| 128 | +There’s no restriction on where you can keep these scripts that work with Player Tags, but you must attach the scripts to a [NetworkObject](../docs/basics/networkobject.md) (such as the Player). |
| 129 | + |
| 130 | +The logic in some of the following examples checks if the Player Tag has a string rather than if it’s equal to a string to allow for more flexibility with the name of the Player Tag. You can also change this logic so that it checks for an exact match. |
| 131 | + |
| 132 | +:::note |
| 133 | +Some of the following examples use the `Contains` method, which is case-sensitive by default, but you can make it case-insensitive by passing the `System.StringComparison.CurrentCultureIgnoreCase` method. |
| 134 | +::: |
| 135 | + |
| 136 | +#### Run as a server, client, or host |
| 137 | + |
| 138 | +The following script uses the Netcode for GameObjects [NetworkManager](../docs/components/networkmanager.md) to automatically connect the Virtual Player as a server, client, or host based on the attached Player Tag. For example, a Player with the “Server” Player Tag automatically runs as a server, and a Player with the “Client” Player Tag automatically runs as a client. |
| 139 | + |
| 140 | +:::note |
| 141 | +This example uses [Netcode for GameObjects (NGO)](../docs/about.md). |
| 142 | +::: |
| 143 | + |
| 144 | +```csharp |
| 145 | +using Unity.Netcode; |
| 146 | +using UnityEngine; |
| 147 | +using Unity.Multiplayer.Playmode; |
| 148 | + |
| 149 | +/// A MonoBehaviour to automatically start Netcode for GameObjects |
| 150 | +/// clients, hosts, and servers |
| 151 | +public class MppmConnect : MonoBehaviour |
| 152 | +{ |
| 153 | + void Start() |
| 154 | + { |
| 155 | + var mppmTag = CurrentPlayer.Tag; |
| 156 | + var networkManager = NetworkManager.Singleton; |
| 157 | + if (mppmTag.Contains("Server")) |
| 158 | + { |
| 159 | + networkManager.StartServer(); |
| 160 | + } |
| 161 | + else if (mppmTag.Contains("Host")) |
| 162 | + { |
| 163 | + networkManager.StartHost(); |
| 164 | + } |
| 165 | + else if (mppmTag.Contains("Client")) |
| 166 | + { |
| 167 | + networkManager.StartClient(); |
| 168 | + } |
| 169 | + } |
| 170 | +} |
| 171 | +``` |
| 172 | + |
| 173 | +#### Automatically assign to team |
| 174 | + |
| 175 | +The following script automatically sets a [NetworkVariable](https://docs-multiplayer.unity3d.com/netcode/current/basics/networkvariable) called `Team` based on the Player Tag. For example, a Player with a Player Tag named “Red” automatically sets the `Team` NetworkVariable to Red. A Player with a Player Tag named “Blue” automatically sets the `Team` NetworkVariable to Blue. |
| 176 | + |
| 177 | +```csharp |
| 178 | +using Unity.Netcode; |
| 179 | +using UnityEngine; |
| 180 | +using Unity.Multiplayer.Playmode; |
| 181 | + |
| 182 | +public enum Team { Blue, Red, } |
| 183 | + |
| 184 | +/// A player with a team that is automatically assigned |
| 185 | +/// based on the Player Tag of the client that owns them |
| 186 | +public class Player : NetworkBehaviour |
| 187 | +{ |
| 188 | + public NetworkVariable<Team> team = new (writePerm: NetworkVariableWritePermission.Owner); |
| 189 | + |
| 190 | + void Start() |
| 191 | + { |
| 192 | + var localClientId = NetworkManager.Singleton.LocalClientId; |
| 193 | + if (!team.CanClientWrite(localClientId)) |
| 194 | + { |
| 195 | + return; |
| 196 | + } |
| 197 | + var mppmTag = CurrentPlayer.Tag; |
| 198 | + if (mppmTag.Contains("Blue")) |
| 199 | + { |
| 200 | + team.Value = Team.Blue; |
| 201 | + } |
| 202 | + if (mppmTag.Contains("Red")) |
| 203 | + { |
| 204 | + team.Value = Team.Red; |
| 205 | + } |
| 206 | + } |
| 207 | +} |
| 208 | +``` |
| 209 | + |
| 210 | +#### Simulate network conditions |
| 211 | + |
| 212 | +The following script uses Network Simulation Presets from the Multiplayer Tools package to automatically apply a fast or slow network based on the Player Tag. In this example, a Player with the “FastNetwork” Player Tag simulates a common [Home Broadband](https://docs-multiplayer.unity3d.com/tools/current/tools-network-simulator#home-broadband) connection, and a Player with the “SlowNetwork” Player Tag simulates a [Mobile 2.5G](https://docs-multiplayer.unity3d.com/tools/current/tools-network-simulator#mobile-25g) connection. |
| 213 | + |
| 214 | +:::note |
| 215 | +This example uses the [Network Simulator](https://docs-multiplayer.unity3d.com/tools/current/tools-network-simulator) tool from the `com.unity.multiplayer.tools` package. |
| 216 | +::: |
| 217 | + |
| 218 | +```csharp |
| 219 | +using System.Collections; |
| 220 | +using System.Collections.Generic; |
| 221 | +using UnityEngine; |
| 222 | +using Unity.Multiplayer.Playmode; |
| 223 | +using Unity.Multiplayer.Tools.NetworkSimulator.Runtime; |
| 224 | + |
| 225 | +public class NetworkSimulatotion : MonoBehaviour |
| 226 | +{ |
| 227 | + void Start() |
| 228 | + { |
| 229 | + var networkSimulator = GetComponent<NetworkSimulator>() ?? |
| 230 | + gameObject.AddComponent<NetworkSimulator>(); |
| 231 | + |
| 232 | + var connectionPreset = NetworkSimulatorPresets.None; |
| 233 | + if (CurrentPlayer.Tag == "FastNetwork") |
| 234 | + { |
| 235 | + connectionPreset = NetworkSimulatorPresets.HomeBroadband; |
| 236 | + } |
| 237 | + else if (CurrentPlayer.Tag == "SlowNetwork") |
| 238 | + { |
| 239 | + connectionPreset = NetworkSimulatorPresets.Mobile2_5G; |
| 240 | + } |
| 241 | + |
| 242 | + networkSimulator.ConnectionPreset = connectionPreset; |
| 243 | + } |
| 244 | +} |
| 245 | +``` |
| 246 | + |
| 247 | +## Synchronized Play mode |
| 248 | + |
| 249 | +When you enter [Play mode](https://docs.unity3d.com/Manual/GameView.html), Multiplayer Play Mode synchronizes the Main Editor and Virtual Players. If you select **Pause** or **Step** in the Main Editor [Toolbar](https://docs.unity3d.com/Manual/Toolbar.html), all Virtual Players follow suit. Enabling **Error Pause** in the [Console](https://docs.unity3d.com/Manual/Console.html) of any Player sets all Virtual Players to pause when you call `Debug.LogError` from a script. |
| 250 | + |
| 251 | +### Using Pause/Step |
| 252 | + |
| 253 | +Because MPPM synchronizes [Play mode](https://docs.unity3d.com/Manual/GameView.html) between the Main Editor and Virtual Players, you can use the Play, Pause, and Step actions the same way you do in a standard Unity Editor workflow. |
| 254 | + |
| 255 | + |
| 256 | + |
| 257 | +1. Selecting **Play** runs all activated Players. |
| 258 | +2. Selecting **Pause** pauses all activated Players. |
| 259 | +3. Selecting **Step** performs a single frame step for all activated Players. |
0 commit comments