Unity multiplayer game development-Netcode for GameObject-official document Chinese translation

Article directory

Official documentation

First, show the document. You can go directly to the official document.
The translation level of official documents
is limited. If there are any errors, please feel free to correct them in the comment area.
Some tutorial links are as follows:
Tutorials

Article version

This article is translated based on Netcode for GameObject 1.5.2 and 1.6.0.
About Netcode for GameObjects: 1.5.2;
Release Notes: 1.5.2;
API Reference: 1.5.2;
Getting Started\Migrating Unity UNet to Netcode for GameObjects (versions of this section and its predecessors): 1.5.2;
Getting Started\Getting Started with NGO (versions of this section and subsequent sections): 1.6.0;

About Netcode for GameObject

Netcode for GameObjects (NGO) is a high-level networking library built for Unity to abstract networking logic. It enables you to send game objects and world data to multiple players over a network session. By using an NGO, you can focus on building games instead of low-level protocols and network frameworks.

To learn more about the features and capabilities of Netcode for GameObjects, check out the following:

Get started

Install Unity Netcode
Migrate from UNet to Netcode
Upgrade to Unity Netcode Package

Start project

Get started with Netcode

Tutorials and examples

Boss Room
Bite Size Samples
Dilmer's Tutorials

Core idea

Network
Component
Object
Message System
Serialization
Scenario

debug

Logging
troubleshooting
error messages

Terminology and FAQs

Advanced Terminology
Multiplayer Game Architecture
FAQ

Don't forget to check out the release notes and API documentation !

before the start

Netcode supports the following versions:

Netcode supports the following platforms:

  • Windows, macOS and Linux
  • iOS and Android
  • XR platform running on Windows, Android and iOS operating systems
  • Most closed platforms , such as game consoles. For more information about specific closed platforms, please contact us. This content is often protected by a confidentiality agreement.
    • When running on a game console (such as PlayStation, Xbox, or Nintendo Switch), there are specific Netcode policies you should be aware of before testing and officially releasing your game. Please refer to your console's internal documentation for more information. Such content is often protected by a confidentiality agreement.

Last updated: August 2, 2023

Release Notes

Netcode for GameObjects

Update log for Netcode for GameObjects

The following content tracks features, updates, bug fixes, and refactorings for the next version of Unity Netcode. Because Netcode for GameObjects is open source, you can access the full release notes and changelog in the GitHub repository at com.unity.netcode.gameobjects .

Release | Date | Update Log
1.5.2 2023-07-24 1.5.2
1.5.1 2023-06-09 1.5.1
1.4.0 2023-04-10 1.4.0
1.3.1 2023-03-27 1.3.1
1.2.0 2022-11-21 1.2.0
1.1.0 2022-10-18 1.1.0
1.0.2 2022-09-08 1.0.2
1.0.1 2022-08-23 1.0.1
1.0.0 2022-06 -27 1.0.0

Last updated: August 14, 2023

Boss Room

Boss Room update log

The following content tracks features, updates, bug fixes, and refactorings for the next version of the Boss Room sample project. Since Boss Room is open source, you can access the full release notes and changelog in the GitHub repository at com.unity.multiplayer.samples.coop .
Release | Date | Update log
2.1.0 2023-04-27 2.1.0
2.0.4 2022-12-14 2.0.4
2.0.3 2022-12-09 2.0.3
All the contents are here, I will not copy them one by one. Yeah, too tired

Last updated: June 13, 2023

Bitesize

Multiplayer Bitesize Example

The following content tracks features, updates, bug fixes, and refactorings for the next version of the multiplayer Bitesize sample project. Since Multiplayer Bitesize is open source, you can access the full release notes and changelog in the GitHub repository at com.unity.multiplayer.samples.bitesize .
Release | Date | Changelog
1.1.0 2022-12-13 1.1.0

Last updated: August 14, 2023

API reference

API reference

start using

Install Netcode for GameObjects

You can use this guide to help you set up Netcode for GameObjects (NGO) in your Unity project.

Prerequisites

Before you start installing Netcode, make sure you have the following:

  • A valid Unity account and license.
  • Supported Unity versions. Please check Netcode's requirements for specific Unity version details.
  • Existing Unity project. If you are new to Unity, you can refer to the Get started with NGO section for guidance.

compatibility

Supported platforms

  • Windows, MacOS and Linux
  • iOS and Android
  • XR platform on Windows, Android and iOS
  • Most closed platforms , such as game consoles. For more information on specific closed platforms, please contact the NGO development team .
  • WebGL (requires NGO 1.2.0+ and UTP 2.0.0+)

Note
When running on closed platforms such as game consoles (PlayStation, Xbox, Nintendo Switch), specific policies and considerations may apply. Please refer to the documentation for your console for more information.

Install NGO using a package manager

  1. Select "Window">"Package Manager" in the Unity editor.
  2. In the package manager, click the “+” Add symbol > “Add package by name…”.
  3. Enter com.unity.netcode.gameobjects into the package name field and select "Add".

Applies to Unity Editor version 2020.3 LTS or earlier

  1. Select Window > Package Manager from the Unity Editor.
  2. In the package manager, click the “+” Add symbol > “Add package by git URL…”
  3. Enter or paste https://github.com/Unity-Technologies/com.unity.netcode.gameobjects into the git URL field and select "Add".

Next step

After installing Netcode for GameObjects (NGO), please refer to the following to continue your journey:

Last updated: August 14, 2023

Upgrade MLAPI to Netcode for GameObjects

Use this guide to upgrade MLAPI 0.1.0 to Netcode for GameObjects (Netcode) 1.0.0

Upgrading to Netcode for GameObjects
It is strongly recommended to upgrade from MLAPI to Netcode for GameObjects as soon as possible. MLAPI is no longer maintained and will not be updated in the future. MLAPI is considered an obsolete product.

Back up your MLAPI project

INFORMATION
Please consider this step a necessary one: upgrading to Netcode's package version may cause problems with your current project. The new version has modified files and locations that are very different from previous MLAPI versions.

Use the following recommended methods to back up your project:

  • Create a copy of your entire project folder.
  • Use source code control software such as Git.

Best Practices
We recommend using these two methods to back up your project. This will give you a duplicate project, tracked by committed changes and history.

Use the upgrade tool on your MLAPI project

Manually upgrading from a MLAPI installed .dll version to a new package version will cause all MLAPI component references in scenes and prefabs to break. Netcode uses a different GUID than the .dll to reference components.

To assist you with the upgrade process to Netcode, we have created an upgrade tool.

To start the upgrade, add the upgrade tool to your project by using the "Add package from git URL..." option in the Package Manager window. Use the following URL:

https://github.com/Unity-Technologies/multiplayer-community-contributions.git?path=/com.unity.multiplayer.mlapi-patcher#release-0.1.0

After installing the update package, you can continue with the upgrade process.

Install Netcode package

Follow the installation guide to install Netcode.

Once the installation is complete, you will see an error message in the console, which is expected behavior since your project now includes both MLAPI and Netcode. This issue will be resolved by the end of this guide.

Installing the Netcode package will also install some other packages, such as Unity Transport, Unity Collections, Unity Burst, etc.

Burst packages require an editor restart. So restart Unity after installation. Unity will ask you to enter failsafe mode on next launch, which is normal behavior because all your networking code no longer compiles.

DANGER
Do not remove older versions of MLAPI yet. It will still be used in the next steps.

Updated script quote

Open the Netcode Patcher window by selecting Window > Netcode Patcher from the menu bar. The patch will ask you if you are using the installation or source version of MLAPI.

There were two main ways to use MLAPI in projects. You can download the release version of MLAPI by using the MLAPI installer, or manually copy the source files into your project.

Tip
If you are not sure which MLAPI method you are using, check if you have the Assets/MLAPI/Lib/MLAPI.dll file in your project. If so, you are using the installed version.

Upgrade from the installation version.

  1. Select Installer.
  2. Select Update Script References.

Upgrade from source version.

  1. Select Source.
  2. The window will prompt you to link to a MLAPI source code directory.
  3. Get the project directory containing the MLAPI source code, drag and drop it into this field.
  4. Select Update Script References.

After completing the patch's "Update Script References" process, the netcode components on your Prefabs and GameObjects should have been updated with their new names.

There is also a "Replace Type Names" button in the Patcher window. This step is optional. It automatically renames old type names in your scripts to API changes in Netcode, saving time on manual renaming. It performs global substitutions on some type names. If you want more control over your changes, you can perform this process manually.

Remove old MLAPI version

Remove any folders containing existing non-package versions of MLAPI from your project. This usually means removing the Assets/MLAPI and Assets/Editor/MLAPI folders from the project.

Upgrade your code to the new Netcode APIs

Information
Code upgrade is a manual and lengthy process. If you encounter difficulties during the upgrade process, please join our Discord and we will provide you with support.

The Unity multiplayer team has tried to keep most of the MLAPI intact in Netcode. However, some changes still need to be made in order to compile successfully.

NetworkVariable changes

The NetworkVariable type now only supports generics, and the type specified in the generic must be a value type. First, change all NetworVariable* types to their generic counterparts. For example, NetworkVariableInt becomes NetworkVariable, NetworkVariableFloat becomes NetworkVariable, and so on. Now, some types (such as string) will not comply with the new type requirements of NetworkVariable. If your type is string, you can use FixedString32Bytes. Note that this type does not allow you to change the size of the string. For custom structures that only contain value types, you can implement the INetworkSerializable interface and it will work fine. Finally, for other types, you will need to create your own NetworkVariable. To do this, create a new class that inherits from NetworkVariableBase and implements all abstract members. If you already had a custom NetworkVariable, now the read and write functions will use our FastBuffer to read from or write to the stream.

Changes in scene management

There are some changes in scene management to unify the way users use it. First, it's now under the NetworkManager singleton. Therefore, you can access it directly via:

var sceneManager = NetworkManager.Singleton.SceneManager;

Next, there is now only one scene event: OnSceneEvent. You can subscribe to it and get scene event information from the SceneEvent class. In this class you will find SceneEventType which will tell you the details of the event type from the scene manager. Finally, the main function for switching between scenes has been changed to match the Unity Scene Manager. Now, you need to call the LoadScene function with two parameters: scene name and LoadSceneMode, which is the standard way of loading scenes in Unity. Instead of using the SwitchScene function.

NetworkBehavior changes

There are two major changes to NetworkBehavior. First, the NetworkStart method became OnNetworkSpawn, and we introduced OnNetworkDespawn to maintain symmetry. Secondly, you now need to override the OnDestroy method because the NetworkBehavior is already using it.

behavioral changes

We try to keep behavioral changes to a minimum, but two of these changes may cause errors in your scripts. First, NetworkManager now closes the connection itself when the application exits. If you implement closing the connection yourself, you will get an error indicating that you tried to disconnect twice. Second, the library now fires the OnValueChanged event for all NetworkVariables after the OnNetworkSpawn (formerly NetworkStart) method returns. You need to refactor scripts that rely on this order accordingly.

Upgrade RPCs

The way RPCs are called in the Netcode version has changed. Please read our new documentation on RPC and replace your existing RPCs with the new system.

Serialization

We replaced the old INetworkSerializable interface with the new INetworkSerializable interface. This interface works a little differently. See INetworkSerializable for details .

The page also provides information about nested serialization types.

SyncVars

In Netcode, SyncVars have been removed. Convert your existing SyncVars to NetworkVariables .

Remove Patcher Package

After the upgrade project is complete, you can remove the Netcode Patcher package in the Unity Package Manager as it is no longer needed.

troubleshooting

Error: Type or namespace named 'MLAPI' not found

If your project uses an assembly definition (.asmdef) file, after switching to the package version, your assembly definition file needs to reference com.unity.multiplayer.mlapi.runtime.

Error: Cannot find type or namespace named 'NetworkedBehaviour'

If you get an error message like this in the console (or a different Netcode type than NetworkedBehaviour), it's most likely because your code uses an outdated API. Open the script indicated in the error message and update all APIs to the new naming.

Error: SerializedObjectNotCreatableException: Object at index 0 is empty

If this happens every time you enter play mode or save a scene, close and reopen the Unity Editor and the problem should be resolved.

Next step

After migrating and updating to Netcode packages, we recommend considering the following:

Last updated on February 2, 2023

Migrate Unity UNet to Netcode for GameObjects

Use this step-by-step guide to migrate your project from Unity UNet to Netcode for GameObjects (Netcode). If you need help, please contact us on the Unity Multiplayer Networking Discord .

UNet is deprecated

UNet is a completely deprecated product and you should upgrade to Netcode for GameObjects as soon as possible.

Current restrictions

Please review the following limitations regarding migrating to Netcode from previous versions of Unity UNet:

  • Naming constraints can cause problems. UNet's methods are prefixed with Cmd or Rpc , while Netcode requires a suffix. This may require complex multi-line regular expressions to find and replace, or manual updates. For example, CommandAttribute has been renamed ServerRpcAttribute and ClientRPCAttribute has been renamed ClientRpcAttribute .
  • Errors with RPC suffix naming patterns cannot be displayed in the IDE.
  • Clients and servers have different representations in UNet. UNet contains some callback functions that do not exist in Netcode.
  • The prefab needs to be added to Netcode's prefab registration list.
  • Netcode currently does not support matching functionality.

Back up your project

Before proceeding with the migration, it is recommended that you back up your project. For example:

  • Create a copy of your entire project folder.
  • Use source code version control software like Git.

Best Practices

It is recommended to use both methods to back up your project. This will give you a duplicate project, tracked by commit changes and history.

Install Netcode and restart Unity

Please refer to the Netcode Installation Guide for more information.

NOTE
If you are installing Git for the first time, you will need to restart your system.

RPC call

The way to call RPC is the same as UNet. Just call the function and it will send an RPC.

Replace NetworkIdentity with NetworkObject

In Netcode, UNet's NetworkIdentity is called NetworkObject and works similarly.

Replace UNet's NetworkTransform with Netcode's NetworkTransform

In Netcode, UNet's NetworkTransform is also called NetworkTransform and works similarly.

NetworkTransform is not completely functionally equivalent to UNET's NetworkTransform . It lacks features such as position synchronization of rigid bodies.

Replace UNet's NetworkAnimator with Netcode's NetworkAnimator

Replace UNet's NetworkAnimator with Netcode's NetworkAnimator component throughout the project .

UpdateNetworkBehaviour

Replace UNet's NetworkBehaviour with Netcode's NetworkBehaviour everywhere in the project .

UNet example

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”);
    }
}

Netcode for GameObjects sample project

public class MyNetcodeExample : NetworkBehaviour
{
    
    
    public NetworkVariable<float> MyNetworkVariable = new NetworkVariable<float>();
    public override void OnNetworkSpawn()
    {
    
    
        ExampleClientRpc(10f);
        ExampleServerRpc(10f);
    }
    [ServerRpc]
    public void ExampleServerRpc(float x)
    {
    
    
        Debug.Log(“Runs on server”);
    }
    [ClientRpc]
    public void ExampleClientRpc(float x)
    {
    
    
        Debug.Log(“Runs on clients”);
    }
}

See NetworkBehaviour for more information.

Replace SyncVar

Replace SyncVar with NetworkVariable and use it everywhere in your project.

To achieve equivalent functionality to the SyncVar hook, subscribe a function to the NetworkVariable 's OnValueChanged callback. One clear difference between the UNet hook and Netcode's OnValueChanged callback is that Netcode will give you the old value and the new value, while UNet will only give you the old value. In UNet, you also need to manually assign the value of SyncVar.

UNET example

public class SpaceShip : NetworkBehaviour
{
    
    
    [SyncVar]
    public string PlayerName;


    [SyncVar(hook = "OnChangeHealth"))]
    public int Health = 42;

    void OnChangeHealth(int newHealth){
    
    
        Health = newHealth; //在 Netcode 中不再需要这一行代码。
        Debug.Log($"我的新health是 {
      
      newHealth}.");
    }
}

Netcode for GameObjects example

// 不要忘记使用一个初始值初始化 NetworkVariable。
public NetworkVariable<string> PlayerName = new NetworkVariable<string>();

public NetworkVariable<int> Health = new NetworkVariable<int>(42);

// 这是如何更新 NetworkVariable 的值的方法,你也可以使用 .Value 来访问 NetworkVariable 的当前值。
void MyUpdate()
{
    
    
    Health.Value += 30;
}


void Awake()
{
    
    
  //  在 Awake 或 Start 中调用此方法来订阅 NetworkVariable 的更改。
    Health.OnValueChanged += OnChangeHealth;
}

void OnChangeHealth(int oldHealth, int newHealth){
    
    
    //现在不再需要手动赋值给变量,Netcode 会自动为你完成。
    Debug.Log($"我的新health是 {
      
      newHealth}. 之前我的health是 {
      
      oldHealth}");
}

Replace all suffix increment and decrement operations in your project with SyncVar. Netcode's NetworkVariable.Value exposes a value type, which is why suffix increment/decrement is not supported.

UNET example


public int Health = 42;

public void Update(){
    
    
  Health++;
}


Netcode for GameObjects sample project


public NetworkVariable<int> Health = new NetworkVariable<int>(42);

public void Update(){
    
    
  Health.Value = Health.Value + 1;
}

Please refer to NetworkVariable for more information.

Replace SyncList with NetworkList

Please replace SyncList with NetworkList everywhere in your project . NetworkList has an OnListChanged event, which is similar to UNet's callback .

UNET example

public SyncListInt m_ints = new SyncListInt();

private void OnIntChanged(SyncListInt.Operation op, int index)
{
    
    
    Debug.Log("列表更改 " + op);
}


public override void OnStartClient()
{
    
    
    m_ints.Callback = OnIntChanged;
}

Netcode for GameObjects example

NetworkList<int> m_ints = new NetworkList<int>();

// 在 Awake 或 Start 中调用此方法来订阅 NetworkList 的更改。
void ListenChanges()
{
    
    
    m_ints.OnListChanged += OnIntChanged;
}

// NetworkListEvent 包含关于操作和更改的索引的信息。
void OnIntChanged(NetworkListEvent<int> changeEvent)
{
    
    

}

Replace Command/ClientRPC

UNet's Command/ClientRPC has been replaced by Server/ClientRpc in Netcode , which works similarly.

UNET example

    [Command]
    public void CmdExample(float x)
    {
    
    
        Debug.Log(“Runs on server”);
    }
    [ClientRpc]
    public void RpcExample(float x)
    {
    
    
        Debug.Log(“Runs on clients”);
    }

Netcode for GameObjects example

    [ServerRPC]
    public void ExampleServerRpc(float x)
    {
    
    
        Debug.Log(“Runs on server”);
    }
    [ClientRPC]
    public void ExampleClientRpc(float x)
    {
    
    
        Debug.Log(“Runs on clients”);
    }

Note
In Netcode, the name of the RPC function must end with the ClientRpc/ServerRpc suffix.

Please check the messaging system for more information.

Replace OnServerAddPlayer

In your project, replace OnServerAddPlayer with ConnectionApproval everywhere .

UNET example

using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.NetworkSystem;

class MyManager : NetworkManager
{
    
    
    public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId, NetworkReader extraMessageReader)
    {
    
    
        if (extraMessageReader != null)
        {
    
    
            var s = extraMessageReader.ReadMessage<StringMessage>();
            Debug.Log("我的名字是" + s.value);
        }
        OnServerAddPlayer(conn, playerControllerId, extraMessageReader);
    }
}

Netcode for GameObjects example

Server only example:

using Unity.Netcode;

private void Setup() 
{
    
    
    NetworkManager.Singleton.ConnectionApprovalCallback += ApprovalCheck;
    NetworkManager.Singleton.StartHost();
}

private void ApprovalCheck(byte[] connectionData, ulong clientId, NetworkManager.ConnectionApprovedDelegate callback)
{
    
    
    // 在这里编写你的逻辑
    bool approve = true;
    bool createPlayerObject = true;

    // 预制体哈希。使用null以使用默认玩家预制体
    // 如果使用这个哈希,请将"MyPrefabHashGenerator"替换为添加到场景中NetworkManager对象的NetworkPrefabs字段的预制体的名称
    ulong? prefabHash = NetworkpawnManager.GetPrefabHashFromGenerator("MyPrefabHashGenerator");
    
    //如果approve为true,则添加连接。如果为false,则断开客户端连接
    callback(createPlayerObject, prefabHash, approve, positionToSpawnAt, rotationToSpawnWith);
}

Please see Connection Approvals for more information.

Replace NetworkServer.Spawn with NetworkObject.Spawn

Replace all NetworkServer.Spawn in the project with NetworkObject.Spawn.

UNET example


using UnityEngine;
using UnityEngine.Networking;

public class Example : NetworkBehaviour
{
    
    
    //在Inspector面板中分配预制体
    public GameObject m_MyGameObject;
    GameObject m_MyInstantiated;

    void Start()
    {
    
    
        //实例化预制体
        m_MyInstantiated = Instantiate(m_MyGameObject);
        //生成在Inspector面板中分配的游戏对象
        NetworkServer.Spawn(m_MyInstantiated);
    }
}

Netcode for GameObjects example

GameObject go = Instantiate(myPrefab, Vector3.zero, Quaternion.identity);
go.GetComponent<NetworkObject>().Spawn();

See Object Generation for more information.

Custom build handler

Netcode has a custom build handler that replaces UNet's custom build function . Please see Object Pools for more information.

Replace NetworkContextProperties

Netcode has IsLocalPlayer , IsClient , IsServer and IsHost to replace UNet's isLocalPlayer , isClient and isServer . In Netcode, each object can be owned by a specific peer. You can check this using IsOwner , which is similar to UNet's hasAuthority .

Network Proximity Checker/OnCheckObserver using Netcode Visibility

There is no direct equivalent of the NetworkPromimityChecker UNet component in Netcode . Network visibility to clients is similar to UNet. Netcode has no equivalent of the ObjectHide message in UNet . In Netcode, network objects on the host are always visible. Netcode does not have an equivalent function to the OnSetLocalVisibility function in UNet . Manual network proximity implementation using OnCheckObserver can be ported to Netcode by using NetworkObject.CheckObjectVisibility . For Netcode's visibility system, OnRebuildObservers are not required .

UNET example

public override bool OnCheckObserver(NetworkConnection conn)
{
    
    
 return IsvisibleToPlayer(getComponent<NetworkIdentity>(), coon);
}

public bool IsVisibleToPlayer(NetworkIdentity identity, NetworkConnection conn){
    
    
    // 任何接近性函数。
    return true;
}

Netcode for GameObjects example

public void Start(){
    
    
    NetworkObject.CheckObjectVisibility = ((clientId) => {
    
    
        return IsVisibleToPlayer(NetworkObject, NetworkManager.Singleton.ConnectedClients[clientId]);
    });
}

public bool IsVisibleToPlayer(NetworkObject networkObject, NetworkClient client){
    
    
    // 任何接近性函数。
    return true;
}

See Object Visibility to learn more about Netcode's network visibility checks.

Update scene management

In Netcode, scene management is not done through NetworkManager like UNet . NetworkSceneManager provides the same functionality for switching scenes.

UNET example

public void ChangeScene()
{
    
    
    MyNetworkManager.ServerChangeScene("MyNewScene");
}

Netcode for GameObjects example

public void ChangeScene()
{
    
    
    NetworkSceneManager.LoadScene("MyNewScene", LoadSceneMode.Single);
}

更新 ClientAttribute/ClientCallbackAttribute 和 ServerAttribute/ServerCallbackAttribute

Currently, Netcode does not provide an alternative to using attributes to mark functions to run only on the server or client. You can manually return in the function to achieve this functionality.

UNET example

[Client]
public void MyClientOnlyFunction()
{
    
    
    Debug.Log("我是客户端!");
}

Netcode for GameObjects example

public void MyClientOnlyFunction()
{
    
    
    if (!IsClient) {
    
     return; }

    Debug.Log("我是客户端!");
}

Use RPC events instead of SyncEvent

Netcode does not provide equivalent functionality for SyncEvent . To port SyncEvent from UNet to Netcode, you can send an RPC to trigger the event on the other end.

UNET example

public class DamageClass : NetworkBehaviour
{
    
    
    public delegate void TakeDamageDelegate(int amount);

    [SyncEvent]
    public event TakeDamageDelegate EventTakeDamage;

    [Command]
    public void CmdTakeDamage(int val)
    {
    
    
        EventTakeDamage(val);
    }
}

Netcode for GameObjects example

public class DamageClass : NetworkBehaviour
{
    
    
    public delegate void TakeDamageDelegate(int amount);

    public event TakeDamageDelegate EventTakeDamage;

    [ServerRpc]
    public void TakeDamageServerRpc(int val)
    {
    
    
        EventTakeDamage(val);
        OnTakeDamageClientRpc(val);
    }

    [ClientRpc]
    public void OnTakeDamageClientRpc(int val){
    
    
        EventTakeDamage(val);
    }
}

network discovery

Netcode does not provide network discovery functionality. The contributed library provides a sample implementation for network discovery .

Next step

After migrating and updating to Netcode packages, we recommend that you refer to the following:

Last updated on February 1, 2023

Start using an NGO

Use this guide to learn how to create your first NGO project. It will guide you to create a simple Hello World project to implement the basic functions of Netcode for GameObjects (NGO).

See Testing the command line helper to learn how to use the command line helper to test your program.

prerequisites

Before you begin, make sure you have the following prerequisites:

  • An active Unity account with valid authorization.
  • Unity Hub
  • A version of the Unity editor that supports NGO. Please refer to NGO requirements .

Before continuing, please create a new project using Unity Editor version 2021.3 or higher.

Tip
If you don't have Assets / Scripts/a folder yet, create one now:

  1. Right-click the Assets folder in the Projects tab and select Create > Folder .
  2. Name the new folder Scripts .

This is where you will save all your scripts.

Install Netcode for GameObjects

Please refer to Installing Netcode for GameObjects .

Add basic components

This section guides you through adding the basic components of an online game:

Create NetworkManager component

This section guides you in creating a NetworkManager component.

First, create the NetworkManager component:

  1. Right-click in the Hierarchy tab and select Create Empty to create an empty GameObject.
    Please add image description
  2. Rename the empty GameObject to NetworkManager.

Please add image description
3. Select NetworkManager and then select Add Component in the Inspector tab .

Please add image description
4. Select Netcode > NetworkManager from the component list .
Please add image description
5. In the Inspector tab, find the Unity Transport section and select UnityTransport as the Protocol type.

Please add image description
Please add image description
6. Press Ctrl/Cmd + S to save the scene (or choose File > Save ).

Create a character object to spawn for each connected player

Tip:
When you put a prefab into the PlayerPrefab slot, you are telling the library that when a client connects to the game, it will automatically generate that prefab as the character for the connected client. If you don't set any prefab as PlayerPrefab , NGO will not generate player objects. Please refer to the player object .

This section guides you through creating an object that is generated for each connected player.

  1. In the Unity Editor, right-click in the Hierarchy tab and select 3D Object > Capsule.
  2. Name the capsule object Player.
  3. With the Player selected, add a NetworkObject component by selecting Add Component > Netcode > NetworkObject in the Inspector tab .
  4. Right-click in the Assets folder under the Project tab and select Create > Folder .
  5. Name the folder Prefabs .
  6. Turn the previously created Player object into a prefab by dragging it from the Hierarchy tab into the Prefabs folder.

Please add image description

  1. Remove the player from the scene by selecting the player capsule in the scene tab and pressing Delete (or Cmd + Delete on macOS ).

Tip
You can remove the player game object from the scene because you assigned the network prefab in the Player prefab property of the NetworkManager component. The library does not support defining player objects as NetworkObjects placed in the scene.

  1. Select NetworkManager .
  2. In the Inspector tab, find the PlayerPrefab field.
    Please add image description
  3. Drag the Player prefab from the Project tab into the PlayerPrefab slot you created in the Inspector tab .
    Please add image description
  4. Add a 3D plane (at 0,0,0) to the scene by right-clicking in the Hierarchy tab and selecting 3D Object > Plane .

Notice

Adding a plane can provide a visual reference point to show the position of the player prefab, but it is not required.

Please add image description

  1. Press Ctrl/Cmd + S (select File > Save ) to save the scene.

Add your scene to the build

This section guides you through adding your scene to your build.

Enabling NetworkManager 's scene management setting allows the server to control which scenes are loaded to the client. However, you must add the current scene to the build to enter Play mode.

NOTE
By default, NetworkManager's scene management option is enabled.

  1. Open the build settings window by selecting File > Build Settings .
  2. Select Add Open Scenes.

Scenes/SampleScene will be listed in the built scene . You can close the build settings window.

Add RPCs

This section guides you through adding basic RPCs to your project.

Tip
If you don't have Assets/Scripts/a folder yet, create one now:

  1. Right-click the Assets folder in the Projects tab and select Create > Folder .
  2. Name the new folder Scripts .
    This will be where you keep all your scripts.

Create a RpcTest.csscript named:

  1. Select Assets > Scripts in the Project tab .
  2. Right-click in the Scripts folder and select Create > C# Script .
  3. Name the script RpcTest.

Add RpcTest.csthe script to the player prefab:

  1. Select the Player prefab in Assets > Prefabs .
  2. In the Inspector tab (with the player prefab selected), select Add Component .
  3. Select Scripts > Rpc Test .

Edit RpcTest.csscript:

  1. Select Assets > Scripts > in the Project tab . RpcTest
  2. In the Inspector tab (with Script selected), select Open . This will open the script in your default local text editor.
  3. Edit RpcTest.csthe script to match the following:
using Unity.Netcode;
using UnityEngine;

public class RpcTest : NetworkBehaviour
{
    
    
    public override void OnNetworkSpawn()
    {
    
    
        if (!IsServer && IsOwner) //只在拥有此 NetworkBehaviour 实例的 NetworkObject 的客户端向服务器发送 RPC
        {
    
    
            TestServerRpc(0, NetworkObjectId);
        }
    }

    [ClientRpc]
    void TestClientRpc(int value, ulong sourceNetworkObjectId)
    {
    
    
        Debug.Log($"客户端接收到 RPC #{
      
      value} on NetworkObject #{
      
      sourceNetworkObjectId}");
        if (IsOwner) //只在拥有此 NetworkBehaviour 实例的 NetworkObject 的客户端向服务器发送 RPC
        {
    
    
            TestServerRpc(value + 1, sourceNetworkObjectId);
        }
    }

    [ServerRpc]
    void TestServerRpc(int value, ulong sourceNetworkObjectId)
    {
    
    
        Debug.Log($"服务器接收到 RPC #{
      
      value} on NetworkObject #{
      
      sourceNetworkObjectId}");
        TestClientRpc(value, sourceNetworkObjectId);
    }
}
  1. Save the scene by pressing Ctrl/Cmd + S (or choose File > Save ).

Test RPCs

This section will guide you through testing the RPCs added in the previous section.

  1. Select File > Build And Run .
  2. Close running games.
  3. Start both the client and the server in a terminal as shown in the Command Line Test Assistant .

Tip
Instead of using the command line helper script, you can use the Multiplayer Play Mode (MPPM) package, which allows you to run multiple instances of the Unity editor to test multiplayer functionality. See Multiplayer Modes for more information.
NOTE : MPPM only supports Unity Editor version 2023.1 and higher.

After the client and server are generated, logs of RPC messages sent to each other are displayed in the consoles of the client and server.

The client initiates the swap for the first time in its OnNetworkSpawn0 call, with a counter value of . It then makes an RPC call to the server using the next value. The server receives this call and calls the client. The console displays the following content for the server and client respectively.

Server Received the RPC #0 on NetworkObject #1
Server Received the RPC #1 on NetworkObject #1
Server Received the RPC #2 on NetworkObject #1
Server Received the RPC #3 on NetworkObject #1
...
Client Received the RPC #0 on NetworkObject #1
Client Received the RPC #1 on NetworkObject #1
Client Received the RPC #2 on NetworkObject #1
Client Received the RPC #3 on NetworkObject #1
...

Only clients with RpcTestscripts NetworkObjectwill send RPCs to the server, but they will all receive RPCs from the server. NetworkObjectThis means that if you are testing with multiple clients, the console will log every RPCs received by the server and all clients in each iteration . If you are testing with a host and a client, you will see the following on the host's console . This is because as a server, it receives server RPCs from other clients, and as a client, it also receives its own client RPCs.

Server Received the RPC #0 on NetworkObject #2
Client Received the RPC #0 on NetworkObject #2
Server Received the RPC #1 on NetworkObject #2
Client Received the RPC #1 on NetworkObject #2
Server Received the RPC #2 on NetworkObject #2
Client Received the RPC #2 on NetworkObject #2
Server Received the RPC #3 on NetworkObject #2
Client Received the RPC #3 on NetworkObject #2
...

NOTE
here NetworkObjectIdis 2because the host also has a RpcTestNetworkObject generated with the script, but it does not send the initial RPC to start the chain since it is the server.

Extend functionality via scripts

This section will show how to use two scripts: HelloWorldPlayer.csand HelloWorldManager.csto extend the functionality of the Hello World project.

HelloWorldManager.csScript

  1. Create a new script named in Scriptsthe folder HelloWorldManager.cs.
  2. Create a new empty object in the scene HelloWorldManagerand attach the script as its component.
  3. Copy the following code into HelloWorldManager.csthe script:
using Unity.Netcode;
using UnityEngine;

namespace HelloWorld
{
    
    
    public class HelloWorldManager : MonoBehaviour
    {
    
    
        void OnGUI()
        {
    
    
            GUILayout.BeginArea(new Rect(10, 10, 300, 300));
            if (!NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer)
            {
    
    
                StartButtons();
            }
            else
            {
    
    
                StatusLabels();

                SubmitNewPosition();
            }

            GUILayout.EndArea();
        }

        static void StartButtons()
        {
    
    
            if (GUILayout.Button("Host")) NetworkManager.Singleton.StartHost();
            if (GUILayout.Button("Client")) NetworkManager.Singleton.StartClient();
            if (GUILayout.Button("Server")) NetworkManager.Singleton.StartServer();
        }

        static void StatusLabels()
        {
    
    
            var mode = NetworkManager.Singleton.IsHost ?
                "Host" : NetworkManager.Singleton.IsServer ? "Server" : "Client";

            GUILayout.Label("Transport: " +
                NetworkManager.Singleton.NetworkConfig.NetworkTransport.GetType().Name);
            GUILayout.Label("Mode: " + mode);
        }

        static void SubmitNewPosition()
        {
    
    
            if (GUILayout.Button(NetworkManager.Singleton.IsServer ? "Move" : "Request Position Change"))
            {
    
    
                if (NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsClient )
                {
    
    
                    foreach (ulong uid in NetworkManager.Singleton.ConnectedClientsIds)
                        NetworkManager.Singleton.SpawnManager.GetPlayerNetworkObject(uid).GetComponent<HelloWorldPlayer>().Move();
                }
                else
                {
    
    
                    var playerObject = NetworkManager.Singleton.SpawnManager.GetLocalPlayerObject();
                    var player = playerObject.GetComponent<HelloWorldPlayer>();
                    player.Move();
                }
            }
        }
    }
}
  1. Read on to understand what the example code means:

In the previous Hello World project, you created a NetworkManager by adding the pre-created NetworkManager component. This component allows you to start a Host, Client or Server in Play mode by inspecting the component. HelloWorldManager.csThe script creates a button menu that appears on the screen when entering Play mode, which simplifies operation.

Tips :

  • Host starts the server and joins as a client.
  • Client joins the server as a client player.
  • Server starts the game as a server and does not instantiate player characters.

HelloWorldManager.csStartButtons()The script implements this menu function through the method. After selecting a button, StatusLabels()the method adds a label to the screen showing the selected mode. This helps differentiate between different game view windows when testing your multiplayer game.

static void StartButtons()
 {
    
    
     if (GUILayout.Button("Host")) NetworkManager.Singleton.StartHost();
     if (GUILayout.Button("Client")) NetworkManager.Singleton.StartClient();
     if (GUILayout.Button("Server")) NetworkManager.Singleton.StartServer();
 }

 static void StatusLabels()
 {
    
    
     var mode = NetworkManager.Singleton.IsHost ?
         "Host" : NetworkManager.Singleton.IsServer ? "Server" : "Client";

     GUILayout.Label("Transport: " +
         NetworkManager.Singleton.NetworkConfig.NetworkTransport.GetType().Name);
     GUILayout.Label("Mode: " + mode);
 }

As shown in the previous code snippet, HelloWorldManager.csthe script also uses an instance of NetworkManager through its singleton to get properties such as IsClient, IsServerand IsLocalClient. IsClientand IsServerattributes indicate the status of the established connection.

HelloWorldManager.csThe script introduces a SubmitNewPosition()new method called , HelloWorldPlayerwhich the script uses to create a simple RPC call .

:::

HelloWorldPlayer.csScript

Tip:
If you don't have Assets/Scripts/a folder yet, create one now:

  1. In the Projects tab, right-click the Assets folder and select Create > Folder .
  2. Name the new folder Scripts .

This is where you will save all your scripts.

  1. Create a new script named in Scriptsthe folder HelloWorldPlayer.cs.
  2. Add this script as a component to your Player prefab.
  3. Copy the following code into HelloWorldPlayer.csthe script:
using Unity.Netcode;
using UnityEngine;

namespace HelloWorld
{
    
    
    public class HelloWorldPlayer : NetworkBehaviour
    {
    
    
        public NetworkVariable<Vector3> Position = new NetworkVariable<Vector3>();

        public override void OnNetworkSpawn()
        {
    
    
            if (IsOwner)
            {
    
    
                Move();
            }
        }

        public void Move()
        {
    
    
            if (NetworkManager.Singleton.IsServer)
            {
    
    
                var randomPosition = GetRandomPositionOnPlane();
                transform.position = randomPosition;
                Position.Value = randomPosition;
            }
            else
            {
    
    
                SubmitPositionRequestServerRpc();
            }
        }

        [ServerRpc]
        void SubmitPositionRequestServerRpc(ServerRpcParams rpcParams = default)
        {
    
    
            Position.Value = GetRandomPositionOnPlane();
        }

        static Vector3 GetRandomPositionOnPlane()
        {
    
    
            return new Vector3(Random.Range(-3f, 3f), 1f, Random.Range(-3f, 3f));
        }

        void Update()
        {
    
    
            transform.position = Position.Value;
        }
    }
}
  1. Read on to understand what the code means:

HelloWorldPlayer.csThe script adds some basic movement functionality to the player character in the Hello World project. Both server players and client players can start moving. However, movement occurs through the server's position NetworkVariable, which means that the server player can move immediately, but the client player must request the move from the server, wait for the server to update the position NetworkVariable, and then copy the changes locally.

HelloWorldPlayerClasses inherit from Unity.Netcode, NetworkBehaviournot MonoBehaviour. This allows you to customize your network code and override events that occur when players spawn.

public class HelloWorldPlayer : NetworkBehaviour

For multiplayer games, each object runs on at least two machines: player one and player two. Therefore, you need to ensure that both machines behave identically and that the information about the objects is correct. One of the things to consider is understanding how the player moves. Only one player can control the movement of the player object. The following code enforces this by verifying that the machine the code is running on is owned by the player.

public override void OnNetworkSpawn()
 {
    
    
     if (IsOwner)
     {
    
    
         Move();
     }
 }

Continuously updating...

Guess you like

Origin blog.csdn.net/weixin_44499065/article/details/132225657