Skip to content

Commit 7962e0f

Browse files
committed
Merge branch 'develop-2.0.0' into fix/v2.x/add-flag-dedicated-server-override
# Conflicts: # com.unity.netcode.gameobjects/Documentation~/TableOfContents.md # com.unity.netcode.gameobjects/Documentation~/configuration.md
2 parents b037cc8 + 6153519 commit 7962e0f

27 files changed

+544
-357
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ Additional documentation and release notes are available at [Multiplayer Documen
2424

2525
### Fixed
2626

27+
- Fixed issue where invoking an RPC, on another `NetworkBehaviour` associated with the same `NetworkObject` that is ordered before the `NetworkBehaviour` invoking the RPC, during `OnNetworkSpawn` could throw an exception if scene management is disabled. (#3782)
28+
- Fixed issue where the `Axis to Synchronize` toggles didn't work with multi object editing in `NetworkTransform`. (#3781)
29+
2730

2831
### Security
2932

com.unity.netcode.gameobjects/Documentation~/TableOfContents.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* [Connection approval](basics/connection-approval.md)
1919
* [Max players](basics/maxnumberplayers.md)
2020
* [Transports](advanced-topics/transports.md)
21-
* [Relay](relay/relay.md)
21+
* [Unity Relay](relay/relay.md)
2222
* Command line arguments
2323
* [Network components](network-components.md)
2424
* [Core components](components/core/corecomponents.md)

com.unity.netcode.gameobjects/Documentation~/configuration.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
Configure your Netcode for GameObjects project.
44

5-
| **Topic** | **Description** |
6-
|:--------------------------------------------------------|:----------------------------------------------------------------------------------------------------|
7-
| **[Configuring connections](configure-connections.md)** | Configure connections in your project. |
8-
| **[Transports](advanced-topics/transports.md)** | Transport layers establish communication between your application and different hosts in a network. |
9-
| **[Relay](relay/relay.md)** | Use Unity Relay with Netcode for GameObjects. |
10-
| **[Command line arguments](command-line-arguments.md)** | Use command line arguments. |
5+
6+
| **Topic** | **Description** |
7+
|:--------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------|
8+
| **[Configuring connections](configure-connections.md)** | Configure connections in your project. |
9+
| **[Transports](advanced-topics/transports.md)** | Transport layers establish communication between your application and different hosts in a network. |
10+
| **[Unity Relay](relay/relay.md)** | Use Unity Relay with Netcode for GameObjects to connect clients and hosts over the internet using a relay server. |
11+
| **[Command line arguments](command-line-arguments.md)** | Use command line arguments. |
Lines changed: 3 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1,178 +1,5 @@
1-
# Using Unity Relay
1+
# Unity Relay
22

3-
With [Netcode for GameObjects](https://docs-multiplayer.unity3d.com/netcode/current/about/) you can use an IP address and a port to connect a client to a host over the internet. However, using an IP address to establish a connection doesn't always work. Instead, you can use [Unity Relay](https://docs.unity.com/ugs/en-us/manual/relay/manual/introduction) to initiate a connection between multiple clients and a host.
3+
Use Unity Relay with Netcode for GameObjects to connect clients and hosts over the internet using a relay server.
44

5-
Many factors impact how you connect to the remote host. To connect to a remote host, use one of the following methods:
6-
7-
* Perform a [NAT punchthrough](../learn/listenserverhostarchitecture.md#option-c-nat-punchthrough): This advanced technique directly connects to the host computer, even if it's on another network.
8-
* Use a [relay server](https://docs.unity.com/relay/en/manual/relay-servers): A relay server exists on the internet with a public-facing IP that you and the host can access. After the client and the host connect to a relay server, they can send data to each other through the relay server.
9-
10-
Netcode for GameObjects doesn't offer tools to help you punch through a NAT. However, you can use the Unity Relay service to relay all technology based on Unity Transport.
11-
12-
## Using Unity Relay
13-
14-
To access a Unity Relay server, do the following:
15-
16-
* As the host, request an allocation on the relay server.
17-
* As a client, use the [join code](https://docs.unity.com/relay/en/manual/join-codes) that the host creates to connect to the relay server. This code allows the host and clients to communicate through the relay server without disclosing their IP addresses and ports directly.
18-
19-
### Enable Unity Relay in a project
20-
21-
To enable and set up Unity Relay in a project, follow the steps in [Get started with Relay](https://docs.unity.com/relay/en/manual/get-started).
22-
23-
### Test the Unity Relay service in the Unity Editor
24-
25-
From Unity version 2022.3, you can test the Relay service with Netcode for GameObjects in the Editor. To do this, do the following:
26-
27-
1. Follow the steps in [Get started with Netcode for GameObjects](https://docs-multiplayer.unity3d.com/netcode/current/tutorials/get-started-ngo/).
28-
2. Follow the steps in [Get started with Relay](https://docs.unity.com/relay/en/manual/get-started).
29-
3. Open the inspector window and select the Network Manager.
30-
4. Navigate to the Start Connection section.
31-
5. Check the **Try Relay in the editor** box.
32-
6. Select **Start Server** or **Start Host** to start the server or host.
33-
7. In the inspector, copy the [join code](https://docs.unity.com/relay/en/manual/join-codes).
34-
8. Enter the join code in a new window running the same project.
35-
9. Select **Start Client**.
36-
37-
This means you don't need to create UI elements to test the Relay service.
38-
39-
If the connection fails then an error message appears in the UI and console.
40-
![](../images/relay/ngo-relay-connection.png)
41-
42-
If Relay connects, a message appears in the inspector that displays the join code.
43-
![](../images/relay/ngo-relay-connected.png)
44-
45-
You can copy the join code to share it, or test it in a project in a separate window. Refer to [testing locally](../tutorials/testing/testing_locally.md) for more details.
46-
47-
> [!NOTE]
48-
> This Relay integration is only available in the Editor, which means you can't use it in a build. Instead, use the code snippets at the end of this page. These snippets use the Unity Transport Package. To do this in projects that don't use Transport, refer to the Relay documentation.
49-
50-
### Create an allocation on a Relay server
51-
52-
To create an [allocation](https://docs.unity.com/relay/en/manual/allocations) on a Relay server, make an authenticated call to the Unity backend using the SDK. To do this, call the `CreateAllocationAsync` method on the host with the maximum number of expected peers. For example, a host that requests a maximum of three peer connections reserves four slots for a four-player game. This function can throw exceptions, which you can catch to learn about the error that caused them.
53-
54-
```csharp
55-
//Ask Unity Services to allocate a Relay server that will handle up to eight players: seven peers and the host.
56-
Allocation allocation = await Unity.Services.Relay.RelayService.Instance.CreateAllocationAsync(7);
57-
```
58-
59-
The `Allocation` class represents all the necessary data for a [host player](https://docs.unity.com/relay/manual/players#Host) to start hosting using the specific Relay server allocated. You don't need to understand each part of this allocation; you only need to feed them to your chosen transport that handles the Relay communication on its own. For reference, here's a simple overview of those parameters:
60-
61-
* A `RelayServer` class containing the IP and port of your allocation's server.
62-
63-
* The allocation ID in a Base64 form and GUID form referred to as `AllocationIdBytes` and `AllocationId`.
64-
65-
* A blob of encrypted bytes representing the [connection data](https://docs.unity.com/relay/en/manual/connection-data) (known as `ConnectionData`) allows users to connect to this host.
66-
67-
* A Base64 encoded `Key` for message signature.
68-
69-
Each allocation creates a unique [join code](https://docs.unity.com/relay/en/manual/join-codes) suitable for sharing over instant messages or other means. This join code allows your clients to join your game. You can retrieve it by calling the Relay SDK like so:
70-
71-
```csharp
72-
string joinCode = await Unity.Services.Relay.RelayService.Instance.GetJoinCodeAsync(allocation.AllocationId);
73-
```
74-
75-
With those two calls, you now have your Relay allocation ready and the associated join code. Pass the allocation parameters to your host transport and send the join code (a simple string) over the Internet by the mean of your choice to your clients.
76-
77-
Remember to [authenticate](https://docs.unity.com/relay/en/manual/authentication) your users before using SDK methods. The easiest way is the anonymous one (shown in the following code snippet), but you can use more advanced techniques.
78-
79-
```csharp
80-
//Initialize the Unity Services engine
81-
await UnityServices.InitializeAsync();
82-
if (!AuthenticationService.Instance.IsSignedIn)
83-
{
84-
//If not already logged, log the user in
85-
await AuthenticationService.Instance.SignInAnonymouslyAsync();
86-
}
87-
```
88-
89-
### Join an allocation on a Relay server
90-
91-
To join an allocation on a Relay server, the following must be true:
92-
93-
* The host of the game has created a Relay allocation.
94-
* The client has received a join code.
95-
96-
To join a relay, a client requests all the allocation parameters from the join code to join the game. To do this, use the join code to call the `JoinAllocationAsync` method as the following code snippet demonstrates:
97-
98-
```csharp
99-
//Ask Unity Services to join a Relay allocation based on our join code
100-
JoinAllocation allocation = await Unity.Services.Relay.RelayService.Instance.JoinAllocationAsync(joinCode);
101-
```
102-
For more information about the join code connection process, refer to [Connection flow](https://docs.unity.com/relay/manual/connection-flow#4).
103-
104-
### Pass allocation data to a transport component
105-
106-
When an allocation exists, you need to make all traffic that comes from Netcode for GameObjects go through the Relay. To do this, perform the following actions to pass the allocation parameters to UnityTransport:
107-
108-
1. Retrieve Unity transport from your NetworkManager:
109-
```csharp
110-
//Retrieve the Unity transport used by the NetworkManager
111-
UnityTransport transport = NetworkManager.Singleton.gameObject.GetComponent<UnityTransport>();
112-
```
113-
114-
2. Call the `SetRelayServerData` method on the retrieved transport by passing the allocation data that you retrieved, as well as the connection type (here set to [dtls](https://docs.unity.com/relay/en/manual/dtls-encryption)). For example:
115-
116-
```csharp
117-
transport.SetRelayServerData(new RelayServerData(allocation, connectionType:"dtls"));
118-
```
119-
120-
3. Call `StartClient`, `StartHost` or `StartServer` and use the Netcode library.
121-
122-
## Code sample
123-
124-
Use the following code to work with the [Relay server](https://docs.unity.com/relay/en/manual/relay-servers). To start a server instead of a host, replace the `StartHost` call with `StartServer` in `StartHostWithRelay`.
125-
126-
For more information, refer to [Unity Relay](https://docs.unity.com/ugs/en-us/manual/relay/manual/introduction).
127-
128-
```csharp
129-
/// <summary>
130-
/// Creates a relay server allocation and start a host
131-
/// </summary>
132-
/// <param name="maxConnections">The maximum amount of clients that can connect to the relay</param>
133-
/// <returns>The join code</returns>
134-
public async Task<string> StartHostWithRelay(int maxConnections=5)
135-
{
136-
//Initialize the Unity Services engine
137-
await UnityServices.InitializeAsync();
138-
//Always authenticate your users beforehand
139-
if (!AuthenticationService.Instance.IsSignedIn)
140-
{
141-
//If not already logged, log the user in
142-
await AuthenticationService.Instance.SignInAnonymouslyAsync();
143-
}
144-
145-
// Request allocation and join code
146-
Allocation allocation = await RelayService.Instance.CreateAllocationAsync(maxConnections);
147-
var joinCode = await RelayService.Instance.GetJoinCodeAsync(allocation.AllocationId);
148-
// Configure transport
149-
NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(new RelayServerData(allocation, "dtls"));
150-
// Start host
151-
return NetworkManager.Singleton.StartHost() ? joinCode : null;
152-
}
153-
154-
/// <summary>
155-
/// Join a Relay server based on the JoinCode received from the Host or Server
156-
/// </summary>
157-
/// <param name="joinCode">The join code generated on the host or server</param>
158-
/// <returns>True if the connection was successful</returns>
159-
public async Task<bool> StartClientWithRelay(string joinCode)
160-
{
161-
//Initialize the Unity Services engine
162-
await UnityServices.InitializeAsync();
163-
//Always authenticate your users beforehand
164-
if (!AuthenticationService.Instance.IsSignedIn)
165-
{
166-
//If not already logged, log the user in
167-
await AuthenticationService.Instance.SignInAnonymouslyAsync();
168-
}
169-
170-
// Join allocation
171-
var joinAllocation = await RelayService.Instance.JoinAllocationAsync(joinCode: joinCode);
172-
// Configure transport
173-
NetworkManager.Singleton.GetComponent<UnityTransport>().SetRelayServerData(new RelayServerData(joinAllocation, "dtls"));
174-
// Start client
175-
return !string.IsNullOrEmpty(joinCode) && NetworkManager.Singleton.StartClient();
176-
}
177-
178-
```
5+
For the most up to date information, refer to [Use Relay with Netcode for GameObjects](https://docs.unity.com/ugs/en-us/manual/relay/manual/relay-and-ngo) in the Multiplayer Services documentation.

com.unity.netcode.gameobjects/Editor/CodeGen/NetworkBehaviourILPP.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,7 @@ private void CreateNetworkVariableTypeInitializers(AssemblyDefinition assembly,
595595
private const string k_NetworkManager_IsServer = nameof(NetworkManager.IsServer);
596596
private const string k_NetworkManager_IsClient = nameof(NetworkManager.IsClient);
597597
private const string k_NetworkManager_LogLevel = nameof(NetworkManager.LogLevel);
598-
599598
private const string k_NetworkBehaviour_rpc_func_table = nameof(NetworkBehaviour.__rpc_func_table);
600-
private const string k_NetworkBehaviour_rpc_name_table = nameof(NetworkBehaviour.__rpc_name_table);
601599
private const string k_NetworkBehaviour_rpc_exec_stage = nameof(NetworkBehaviour.__rpc_exec_stage);
602600
private const string k_NetworkBehaviour_NetworkVariableFields = nameof(NetworkBehaviour.NetworkVariableFields);
603601
private const string k_NetworkBehaviour_beginSendServerRpc = nameof(NetworkBehaviour.__beginSendServerRpc);

com.unity.netcode.gameobjects/Editor/CodeGen/RuntimeAccessModifiersILPP.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,12 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition)
151151
{
152152
fieldDefinition.IsFamilyOrAssembly = true;
153153
}
154-
154+
#if MULTIPLAYER_TOOLS && (DEVELOPMENT_BUILD || UNITY_EDITOR || UNITY_MP_TOOLS_NET_STATS_MONITOR_ENABLED_IN_RELEASE)
155155
if (fieldDefinition.Name == nameof(NetworkBehaviour.__rpc_name_table))
156156
{
157157
fieldDefinition.IsFamilyOrAssembly = true;
158158
}
159+
#endif
159160
}
160161

161162
foreach (var methodDefinition in typeDefinition.Methods)

com.unity.netcode.gameobjects/Editor/CodeGen/Unity.Netcode.Editor.CodeGen.asmdef

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@
2424
"name": "com.unity.nuget.mono-cecil",
2525
"expression": "(0,1.11.4)",
2626
"define": "CECIL_CONSTRAINTS_ARE_TYPE_REFERENCES"
27+
},
28+
{
29+
"name": "com.unity.multiplayer.tools",
30+
"expression": "",
31+
"define": "MULTIPLAYER_TOOLS"
2732
}
2833
],
2934
"noEngineReferences": false

com.unity.netcode.gameobjects/Editor/NetworkTransformEditor.cs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ private void DisplayNetworkTransformProperties()
107107
rect = EditorGUI.PrefixLabel(rect, ctid, s_PositionLabel);
108108
rect.width = s_ToggleOffset;
109109

110-
m_SyncPositionXProperty.boolValue = EditorGUI.ToggleLeft(rect, "X", m_SyncPositionXProperty.boolValue);
110+
DrawToggleProperty(rect, "X", m_SyncPositionXProperty);
111111
rect.x += s_ToggleOffset;
112-
m_SyncPositionYProperty.boolValue = EditorGUI.ToggleLeft(rect, "Y", m_SyncPositionYProperty.boolValue);
112+
DrawToggleProperty(rect, "Y", m_SyncPositionYProperty);
113113
rect.x += s_ToggleOffset;
114-
m_SyncPositionZProperty.boolValue = EditorGUI.ToggleLeft(rect, "Z", m_SyncPositionZProperty.boolValue);
114+
DrawToggleProperty(rect, "Z", m_SyncPositionZProperty);
115115

116116
GUILayout.EndHorizontal();
117117
}
@@ -126,11 +126,11 @@ private void DisplayNetworkTransformProperties()
126126
rect = EditorGUI.PrefixLabel(rect, ctid, s_RotationLabel);
127127
rect.width = s_ToggleOffset;
128128

129-
m_SyncRotationXProperty.boolValue = EditorGUI.ToggleLeft(rect, "X", m_SyncRotationXProperty.boolValue);
129+
DrawToggleProperty(rect, "X", m_SyncRotationXProperty);
130130
rect.x += s_ToggleOffset;
131-
m_SyncRotationYProperty.boolValue = EditorGUI.ToggleLeft(rect, "Y", m_SyncRotationYProperty.boolValue);
131+
DrawToggleProperty(rect, "Y", m_SyncRotationYProperty);
132132
rect.x += s_ToggleOffset;
133-
m_SyncRotationZProperty.boolValue = EditorGUI.ToggleLeft(rect, "Z", m_SyncRotationZProperty.boolValue);
133+
DrawToggleProperty(rect, "Z", m_SyncRotationZProperty);
134134

135135
GUILayout.EndHorizontal();
136136
}
@@ -150,11 +150,11 @@ private void DisplayNetworkTransformProperties()
150150
rect = EditorGUI.PrefixLabel(rect, ctid, s_ScaleLabel);
151151
rect.width = s_ToggleOffset;
152152

153-
m_SyncScaleXProperty.boolValue = EditorGUI.ToggleLeft(rect, "X", m_SyncScaleXProperty.boolValue);
153+
DrawToggleProperty(rect, "X", m_SyncScaleXProperty);
154154
rect.x += s_ToggleOffset;
155-
m_SyncScaleYProperty.boolValue = EditorGUI.ToggleLeft(rect, "Y", m_SyncScaleYProperty.boolValue);
155+
DrawToggleProperty(rect, "Y", m_SyncScaleYProperty);
156156
rect.x += s_ToggleOffset;
157-
m_SyncScaleZProperty.boolValue = EditorGUI.ToggleLeft(rect, "Z", m_SyncScaleZProperty.boolValue);
157+
DrawToggleProperty(rect, "Z", m_SyncScaleZProperty);
158158

159159
GUILayout.EndHorizontal();
160160
}
@@ -281,6 +281,28 @@ private void DisplayNetworkTransformProperties()
281281
#endif // COM_UNITY_MODULES_PHYSICS2D
282282
}
283283

284+
/// <summary>
285+
/// Draw a ToggleLeft property field so it will support multi selection editing if applicable.
286+
/// </summary>
287+
private void DrawToggleProperty(Rect rect, string label, SerializedProperty property)
288+
{
289+
if (property.hasMultipleDifferentValues)
290+
{
291+
EditorGUI.showMixedValue = true;
292+
EditorGUI.BeginChangeCheck();
293+
bool enabled = EditorGUI.ToggleLeft(rect, label, property.boolValue);
294+
if (EditorGUI.EndChangeCheck())
295+
{
296+
property.boolValue = enabled;
297+
}
298+
EditorGUI.showMixedValue = false;
299+
}
300+
else
301+
{
302+
property.boolValue = EditorGUI.ToggleLeft(rect, label, property.boolValue);
303+
}
304+
}
305+
284306
/// <inheritdoc/>
285307
public override void OnInspectorGUI()
286308
{

0 commit comments

Comments
 (0)