Using the NetworkManager

使用NetworkManager(网络工程管理器)

The NetworkManager is acomponent for managing the network state of a multiplayer game. It is actuallyimplemented entirely using the HLAPI, so everything it does is available todevelopers in other forms. However the NetworkManager wraps up a lot of usefulfunctionality into a single place and makes creating, running and debuggingmultiplayer games as simple as possible.

NetworkManager(网络工程管理器)是一个用来管理多人在线游戏网络状态的组件。他实际上是完全使用HLAPI(High Level API网络高级编程接口)来实现的,开发者也能用它来做其他形式的网络编程。NetworkManager封装了很多很有用的方法来让创建、运行、调试多人在线游戏变得非常的简单可行。

The NetworkManager can beused entirely without scripting. It has inspector controls in the editor thatallow configuration of all of its features. The NetworkManagerHUD supplies asimple, default user interface at runtime that allows the network game to becontrolled by the user. For advanced uses, developers can derive a class fromNetworkManager and customize its behaviour by overriding any of the virtualfunction hooks that it provides.

使用NetworkManager的时候可以不用编写任何脚本。它拥有在编辑器的inspector(审查)视图中可以控制各种配置的特性。在运行的时候,NetworkManagerHUD提供了一个简单通用的用户接口可以让用户来控制联网游戏。对高级用户,开发者可以从NetworkManager继承一个类,通过重写各种虚函数来提供一个自定义的网络游戏管理行为。

The NetworkManager featuresinclude:

NetworkManager有以下特性:

. Game State Management

. Spawning Management

. Scene Management

. Debugging Information

. Matchmaking

. Customization

.管理游戏状态

.管理各种生成器

.管理各个场景的切换

.调试信息的显示

.进行联网匹配

.用户自由定制

Getting Started with NetworkManager

NetworkManager入门

The NetworkManager can beused as the core controlling component of a multiplayer game. To get started,create an empty game object in your starting scene, or pick a convenientmanager object. Then add the NetworkManager component from the Network/NetworkManagermenu item. The newly added NetworkManager component should look something like:

在一个多人在线游戏中,NetworkManager是一个核心控制组件。第一步,在场景中创建一个空的游戏对象或者选择一个可以用于管理的对象。然后将Network中的NetworkManager组件添加到对象上。新添加的NetworkManager组件显示如下:

wKioL1cjF_viCpLgAABpCX533Wc037.png

The inspector for theNetworkManager in the editor allows you to configure and control many thingsrelated to networking.

在编辑器的Inspector(审查)视图中你可以控制很多网络相关的配置。

The NetworkManagerHUD isanother component that works with the NetworkManager. It gives you a simpleuser interface when the game is running to control the network state. This isgood for getting started with a network project, but not intended to be used asthe final UI for a game. The NetworkManagerHUD looks like:

NetworkManagerHUD(网络管理器导航)是另一个可以与NetworkManager搭配使用的组件。它在游戏运行的时候会提供一个简单的交互界面供用户控制网络状态。这是在进行网络编程入门时非常有帮助的一个组件,但并不是一个游戏最终的界面。NetworkManagerHUD的界面如下:

wKiom1cjFzvTIKCIAABiS_YuDrE436.pngwKiom1cjF0Xg0RwgAACRikTMBlg867.png

Real games will have a properuser interface for controlling the game state and to allow players to choosewhat kind of game to play. But, to get started, we can use this to control thegame.

真实的游戏会有其适配的用户界面来控制游戏状态,来让用户选择想要进行什么类型的游戏。但在初学的时候,我们可以先用这个来进行联网游戏的控制。

Game State Management

游戏状态管理

A Networking multiplayer gamecan run in three modes - as a client, as a dedicated server, or as a “Host”which is both a client and a server at the same time. Networking is designed tomake the same game code and assets work in all of these cases. Developing forthe single player version of the game and the multiplayer version of the gameshould be the same thing.

一个联网多人游戏可以以三种模式来运行 – 客户端,服务器,还有一个同时兼有服务器与客户端的“主机”。联网工程就是设计一个能够在这三种情况下保持有同样代码同样资源的工作。开发单人游戏版本和多人游戏版本实际上并没有太大的差别。

NetworkManager has methodsfor entering each of these modes. NetworkManager.StartClient(),NetworkManager.StartServer() and NetworkManager.StartHost() are all availableto script code, so they can be invoked from keyboard input handlers or fromcustom user interfaces. The default runtime controls that can optionally bedisplayed also invoke these same functions. There are also buttons in theNetworkManagerHUD inspector available when in play mode that call the samefunctions:

NetworkManager提供了一些方法用来进入这3种模式。

脚本代码中提供了NetworkManager.StartClient(),NetworkManager.StartServer()和NetworkManager.StartHost()这3个函数,可以通过键盘时间或者用户界面来调用这些函数。运行时,可以任选其中几种模式显示给用户。NetworkManagerHUD在运行时提供了几种按钮来供用户选择进入哪一种模式。

wKioL1cjGCLw6mZGAACr3sRIuS8933.png

Whatever method is used tochange the game state, the properties networkAddress and networkPort are used.When a server or host is started, networkPort becomes the listen port. When aclient is started, networkAddress is the address to connect to, and networkPortis the port to connect to.

无论如何调用函数,都会用到networkAddress(网络地址)和networkPort(网络端口)这两个参数。当一个服务器或者主机运行的时候,设置的网络端口就是监听端口。当一个客户端运行的时候,网络地址是想要连接的目标地址,网络端口是想要连接的目标端口。

Spawning Management

生成器管理

The NetworkManager can beused to manage spawning of networked objects from prefabs. Most games have aprefab used as the main player object, so the NetworkManager has a slot to dragthe player prefab. When a player prefab is set, a player object will automaticallybe spawned from that prefab for each user in the game. This applies to thelocal player on a hosted server, and remote players on remote clients. Notethat the player prefab must have the NetworkIdentity component on it.

NetworkManager可以用来管理从预制生成各种联网对象。大部分游戏都会有一个用来作为主要玩家角色的对象,所以NetworkManager提供了一个可以拖放玩家预制的槽。当设置好一个玩家预制,在玩家进入游戏的时候,服务器会用玩家预制来为每一个玩家创建一个玩家对象。这个同样也应用于主机模式下的本地玩家,和连到主机的远程客户端的远程玩家。注意,玩家预制必须含有一个NetworkIdentity(联网×××)组件。

In addition to the playerprefab, the prefabs of other objects that will be dynamically spawned must beregistered with the ClientScene. This can be done with theClientScene.RegisterPrefab() functions, or it can be done by the NetworkManagerautomatically. Adding prefabs to the spawn list will make them beauto-registered. The spawn configuration section of the NetworkManagerinspector looks like:

除此之外,其他动态生成的联网对象也都需要在ClientScene(客户端场景)进行注册。ClientScene.RegisterPrefab()函数提供了处理方法。或者可以使用NetworkManager来自动处理。将各个预制添加到生成列表里可以让这些预制被自动注册。NetworkManager在inspector(审查)视图的生成配置如下:

wKiom1cjF2HzGWLPAACGC_9kdmY408.png

Once a player prefab is set,you should be able to start the game as a host and see the player object bespawned. Stopping the game should make the player object be destroyed. Runninganother copy of the game and connecting as a client to localhost should makeanother player object appear, and stopping that client should make thatclient’s player object be destroyed.

当设置好一个玩家预制,你可以在开始一个主机游戏的时候看到一个玩家预制被生成。退出游戏的时候你会看到那个玩家预制会被销毁。运行另一个独立的客户端来连接到本地主机,你会看到有另外的玩家预制出现,退出那个客户端的话,相应客户端的玩家预制会被销毁。

The player object is spawnedby the default implementation of NetworkManager.OnServerAddPlayer. If you wantto customize the way player objects are created, you can override that virtualfunction. The default implementation is something like:

玩家预制是由NetworkManager.OnServerAddPlayer的默认实现生成的。如果你想要自定义玩家对象的创建,你可以重写这个虚函数,默认的派生实现如下:

public virtual voidOnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
    var player =(GameObject)GameObject.Instantiate(playerPrefab, playerSpawnPos,Quaternion.identity);
    NetworkServer.AddPlayerForConnection(conn,player, playerControllerId);
}


Note that the functionNetworkServer.AddPlayerForConnection() must be called for the newly createdplayer object so that it is spawned and associated with the client’s connection.This will Spawn the object, so NetworkServer.Spawn does not need to be calledfor the player object.

注意,NetworkServer.AddPlayerForConnection()函数必须在创建新玩家对象的时候调用,那样才能为客户端生成相关的玩家对象。这样就生成了玩家对象,所以不用在玩家对象代买中再中调用NetworkServer.Spawn

Start Positions

起始位置

To control where players arespawned, you can use the NetworkStartPosition component. The NetworkManagerlooks for NetworkStartPosition objects in a scene, and if it finds any, then itwill spawn player at the position and orientation of one of them. Custom codecan access the available NetworkStartPositions by the listNetworkManager.startPositions, and there is also a helper functionGetStartPosition() on the NetworkManager that can be used in implementation ofOnServerAddPlayer to find a start position.

你可以使用NetworkStartPosition来控制玩家对象在何处被生成。NetworkManager会查找场景中所有带有NetworkStartPosition(联网起始位置)组件的对象,如果有找到相关的对象,玩家对象将会以其中某一个的位置与方向来创建。使用NetworkManager.StartPositions可以获取到场景中可以使用的所有起始位置对象,还有一个很有帮助的函数GetStartPosition(),这个函数是NetworkManager下的函数,可以在其派生类的OnServerAddPlayer中为玩家预制找到一个起始点。

To use start positions,attach a NetworkStartPosition component to an object in the play scene. Therecan be multiple start positions within a scene. The NetworkManager will thenregister the position and orientation of the object as a start position. When aclient joins the game and a player is added, the player object will be createdat one of the start positions, with the same position and orientation.

想要使用其实位置,将NetworkStartPosition组件添加到场景中的一个对象上。一个场景可以有多个起始位置对象。NetworkManager将会自动注册这些起始位置对象的坐标和方向。当一个客户端加入了游戏,一个玩家进入时,玩家预制将会以某一个起始位置的坐标和方向被创建出来。

The NetworkManager has aproperty PlayerSpawnMethod which allows configuration of how start positionsare chosen.

NetworkManager有一个参数PlayerSpawnMethod(玩家生成函数)可以用来配置起始位置的选择方式。

Scene Management

场景管理

Most games have more than onescene. At very least there is usually a title screen or starting menu scene inaddition to the scene where the game is actually played. The NetworkManager issetup to automatically manage scene state and scene transitions in a way thatworks for a multiplayer game. There are two slots on the NetworkManagerinspector, the offlineScene and the onlineScene. Dragging scene objects intothese slots activates networked scene management.

大多数游戏会有不止一个场景。在游戏运行的时候通常至少会有一个小场景或者一个开始菜单场景。NetworkManager为多人在线游戏设置了一套自动切换场景状态的管理机制。在NetworkManager的inspector(审查)视图上有两个槽,offlineScene(离线场景)和onlineScene(在线场景)。将场景对象拖到这两个槽上来激活场景管理机制。

When a server or host isstarted, the online scene will be loaded. This will then become the currentnetwork scene. Any clients that connect to that server will be instructed toalso load that scene. The name of this scene is stored in the networkSceneNameproperty.

当一个服务器或者主机开始运行,在线场景将会被读取出来。然后当前场景将会切换到在线场景。任何连接到服务器的客户端也将会被通知加载这个场景。这个场景的名称将会被储存在networkSceneName变量中

When the network is stopped,by stopping the server or host, or by a client disconnecting, the offline scenewill be loaded. This allows the game to automatically return to a menu scenewhen disconnected from a multiplayer game.

当服务器或者主机退出或者客户端断开连接导致网络连接断开时,离线场景将会被加载。这个可以让游戏在断开连接时返回到菜单场景

You can also change sceneswhile the game is active by calling NetworkManager.ServerChangeScene(). Thiswill make all the currently connected clients change scene too, and will updatenetworkSceneName so that new clients will also load the new scene.

你也可以在游戏被激活的时候通过调用NetwrokManager.ServerChangeScene()来切换场景。这将会使当前连接的所有客户端也切换场景,同时也会更新当前的networkSceneName变量,这样新连接的客户端也将读取这个新场景。

While networked scenemanagement is active, any calls to game state managerment functions suchNetworkManager.StartHost() or NetworkManager.StopClient() can cause scenechanges. This applies to the runtime control UI. So by setting up scenes andcalling these functions it is easy to control the flow of a multiplayer game.

在联网场景管理被激活的期间,任何游戏状态相关的函数被调用的时候都会导致场景的切换,类似NetworkManager.StartHost()和NetworkManager.StopClient()。这些都适用在游戏运行期间的控制UI上。所以设置这些场景,调用这些方法,可以很容易的控制一个多人在线游戏的流程。

Note that scene changes causeall the objects in the scene to be destroyed. This could include theNetworkManager! If you want the NetworkManager to persist between scenes, thenensure the “Dont Destroy On Load” checked boxed is set to true. In simplecases, this is the best configuration. But, it is possible to have aNetworkManager in each scene with different settings to control incrementalprefab loading, or different scene transitions.

注意,场景切换的时候,场景中所有的对象将会被销毁。可能会包含NetworkManager!如果你希望NetworkManager在各个场景中一直保留,确保“Don’t Destroy OnLoad”(加载时不销毁)勾选项是被勾选的。在一个简单的例子中,这是最好的配置。但是,这可能会导致有不同设置的NetworkManager在每个场景中越来越多,或者在不同场景切换的时候越来越多。

Debugging Information

调试信息

The NetworkManagerHUDinspector panel shows additional information about the state of the network atruntime. This includes:

在联网运行时,NetworkManagerHUD(联网管理器导航)的inspector(审查)面板上会显示附加的网络状态信息。其中包含有:

. network connections

. active NetworkIdentityserver objects

. active NetworkIdentityclient objects

. client peers

. 网络的连接

. 激活的服务器对象的×××信息

. 激活的客户端对象的×××信息

. 客户端节点

Also, registered clientmessage handlers are shown in the preview window.

同样,注册上的客户端信息也会显示在预览窗口中。

wKioL1cjGGbSdb7uAAChf8T6Im8223.png

Matchmaking

匹配联网比赛

The NetworkManager runtime UIand NetworkManager inspector UI allow interactions with the matchmaker service.The function NetworkManager.StartMatchmaker() enables matchmaking, andpopulates the NetworkManager.matchmaker property with a NetworkMatch object.Once this is active, the default UIs use it and callback functions onNetworkManager to let you perform simple matchmaking.

NetworkManager的运行时UI和inspector面板UI提供了比赛匹配的交互服务。NetworkManager.StartMatchmaker()提供了匹配方法,其结果将会被赋值到联网比赛对象的NetworkManager.matchmaker属性上。当比赛被激活时,默认的UI可以在NetworkManager上进行回调来让你进行一个简单的比赛匹配。

There are virtual functionson NetworkManager that derived classes can use to customize behaviour ofresponding to matchmaker callbacks.

NetworkManager的派生类有一些虚函数可以通过一些自定义的行为来相应匹配比赛的回调

wKiom1cjF6Sx-7mxAADeCv2jF40795.png

Customization

用户自定义

There are virtual functionson NetworkManager that derived classes can use to customize behaviour. Whenimplementing these functions, be sure to take care of the functionality thatthe default implementations provide. For example, in OnServerAddPlayer(), thefunction NetworkServer.AddPlayer must be called to active the player object forthe connection.

NetworkManager有一些虚函数,开发者可以通过派生类中对这些虚函数的实现来自定义一个新的脚本行为。当实现这些方法时,一定要注意默认实现提供的方法。例如,在OnServerAddPlayer()中,NetworkServer.AddPlayer一定要在玩家对象激活时被调用

Functions invoked on theServer/Host:

服务器/主机的方法调用:

// called when a clientconnects 
//在客户端连接时调用
public virtual void OnServerConnect(NetworkConnectionconn);
 
// called when a clientdisconnects
// 客户端断开连接时调用
public virtual voidOnServerDisconnect(NetworkConnection conn)
{
   NetworkServer.DestroyPlayersForConnection(conn);
}
 
// called when a client isready
// 客户端准备好的时候调用
public virtual voidOnServerReady(NetworkConnection conn)
{
    NetworkServer.SetClientReady(conn);
}
 
// called when a new playeris added for a client
// 在一个新玩家客户端加入时调用
public virtual voidOnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
    var player =(GameObject)GameObject.Instantiate(playerPrefab, playerSpawnPos,Quaternion.identity);
    NetworkServer.AddPlayerForConnection(conn,player, playerControllerId);
}
 
// called when a player isremoved for a client
// 在玩家客户端被移除时调用
public virtual voidOnServerRemovePlayer(NetworkConnection conn, short playerControllerId)
{
    PlayerController player;
    if (conn.GetPlayer(playerControllerId, outplayer))
    {
        if (player.NetworkIdentity != null&& player.NetworkIdentity.gameObject != null)
            NetworkServer.Destroy(player.NetworkIdentity.gameObject);
    }
}
 
// called when a networkerror occurs
// 当有网络连接发生错误时调用
public virtual voidOnServerError(NetworkConnection conn, int errorCode);


Functions invoked on theClient:

客户端方法调用:

// called when connected to aserver
// 在连接到服务器时调用
public virtual voidOnClientConnect(NetworkConnection conn)
{
    ClientScene.Ready(conn);
    ClientScene.AddPlayer(0);
}
 
// called when disconnectedfrom a server
// 在断开与服务器的连接时调用
public virtual voidOnClientDisconnect(NetworkConnection conn)
{
    StopClient();
}
 
// called when a networkerror occurs
// 在连接发生错误时调用
public virtual voidOnClientError(NetworkConnection conn, int errorCode);
 
// called when told to benot-ready by a server
// 在被告知服务器未准备好时调用
public virtual voidOnClientNotReady(NetworkConnection conn);


Functions invoked for theMatchmaker:

比赛匹配调用函数:

// called when a match iscreated
// 在匹配被创建时调用
public virtual voidOnMatchCreate(CreateMatchResponse matchInfo)
 
// called when a list ofmatches is received
// 在收到匹配列表时调用
public virtual voidOnMatchList(ListMatchResponse matchList)
 
// called when a match isjoined
// 在加入比赛时调用
public voidOnMatchJoined(JoinMatchResponse matchInfo)