Unity+ Photon服务器实时对战游戏——主服务器和大厅(四)

时间:2022-11-07 17:55:43

Master Server And Lobby 主服务器和大厅

PUN always uses a master server and one or more game servers. The master server manages currently running games on the various game servers and will provide a game server address when you join or create a room. PUN (the client) automatically switches to that game server.

PUN总是使用一个主服务器和一个或多个游戏服务器。 主服务器管理当前运行游戏的各种游戏服务器和将提供一个游戏服务器地址当你加入或创建一个房间。 PUN(客户端),它会自动切换到游戏服务器。

Individual matches are known as Rooms. They are independent of each other and identified by name. Rooms are grouped into one or multiple lobbies. Lobbies are an optional part in matchmaking. If you don't use custom lobbies explicitly, PUN will use a single lobby for all rooms.

个人比赛房间。 他们是相互独立的和确定的名字。 房间都分成一个或多个游说团体。 大堂是一个可选的相亲。 如果你不使用自定义显式地游说,PUN将为所有房间使用一个大厅。

By default, PUN will join the default lobby after connecting. This lobby sends a list of existing rooms to the client, so the player can pick a room (by name or some properties listed). Access the current list by using PhotonNetwork.GetRoomList(). The lists is updated in intervals to keep traffic low.

默认情况下,PUN将加入连接后默认的游说。 这个大厅发送客户端现有的房间列表,所以玩家可以选择一个房间(按名称或列出一些属性)。 通过使用PhotonNetwork.GetRoomList访问当前列表()。 的列表更新间隔保持低流量。

Clients don't have to join a lobby to join or create rooms. If you don't want to show a list of rooms in your client, set PhotonNetwork.autoJoinLobby = false before you connect and your clients will skip the lobby.

客户不需要加入一个游说加入或创建房间。 如果你不想显示一个房间在您的客户端列表,设置PhotonNetwork。 autoJoinLobby = false之前你连接,你的客户会跳过大厅。

You can use more than one lobby to organize room-lists as needed for your game. PhotonNetwork.JoinLobby is the method to join a specific lobby. You can make them up on the client side - the server will keep track of them. As long as name and type are the same, the TypedLobby will be the same for all clients, too.

您可以使用一个以上的游说组织room-lists作为你的游戏需要。 PhotonNetwork。 JoinLobby方法加入特定的游说。 你可以让他们在客户端-服务器将跟踪他们。 只要名称和类型是相同的,所有客户的TypedLobby将是相同的。

A client is always just in one lobby and while being in a lobby, creating a room will relate to this lobby, too. Multiple lobbies mean the clients get shorter rooms lists, which is good. There is no limit to the rooms lists.

客户总是在一个游说团体在游说,创建一个房间也会与这个大厅。 多个游说团体意味着客户端变短的房间列表,这是好的。 是没有限制的房间列表。

A parameter in JoinRoom, JoinRandomRoom and CreateRoom enables you to select a lobby without joining it.

JoinRoom中的一个参数,JoinRandomRoom CreateRoom使您能够选择一个游说没有加入它。

Players won't notice each other in the Lobby and can't send data (to prevent issues when it's getting crowded).

玩家不会注意到彼此在大堂,不能发送数据(防止问题的时候拥挤)。

The servers are all run on dedicated machines - there is no such thing as player-hosted ‘servers’. You don’t have to bother remembering about the server organization though, as the API all hides this for you.

服务器都运行在专用的机器——不存在player-hosted“服务器”。 你不必费心记住关于服务器组织,API都隐藏这对你。
PhotonNetwork.ConnectUsingSettings(“v1.0“);

The code above is required to make use of any PhotonNetwork features. It sets your client’s game version and uses the setup-wizard’s config (stored in: PhotonServerSettings). The wizard can also be used when you host Photon yourself. Alternatively, use Connect() and you can ignore the PhotonServerSettings file.

上面的代码应使用任何PhotonNetwork特性。 它集客户的游戏版本和使用安装向导的配置(存储在:PhotonServerSettings)。 向导还可以使用当你自己主机Photon。 另外,使用Connect()和可以忽略PhotonServerSettings文件。

Versioning 版本控制

The loadbalancing logic for Photon uses your appID to separate your players from anyone else’s. The same is done by game version, which separates players with a new client from those with older clients. As we can’t guarantee that different Photon Unity Networking versions are compatible with each other, we add the PUN version to your game’s version before sending it (since PUN v1.7).

负载平衡Photon逻辑使用appID分离你从别人的玩家。 同样是通过游戏版本,将玩家与一个新客户的老客户。 我们不能保证不同Photon相互兼容Unity网络版本,我们将双关语版本添加到您的游戏版本,然后再把它寄(因为双关语v1.7)。

Creating and Joining Games 创建和加入游戏

Next, you’ll want to join or create a room. The following code showcases some required functions: 接下来,您将想要加入或创建一个房间。 下面的代码展示了一些需要的功能:

//Join a room 加入房间
PhotonNetwork.JoinRoom(roomName);
//Create this room. 创建一个房间
PhotonNetwork.CreateRoom(roomName);
// Fails if it already exists and calls: OnPhotonCreateGameFailed 失败,如果它已经存在并调用:OnPhotonCreateGameFailed
//Tries to join any random game: 试图加入任何随机的游戏:
PhotonNetwork.JoinRandomRoom();
//Fails if there are no matching games: OnPhotonRandomJoinFailed

A list of currently running games is provided by the master server’s lobby. It can be joined like other rooms but only provides and updates the list of rooms. The PhotonNetwork plugin will automatically join the lobby after connecting. When you’re joining a room, the list will no longer update.

当前运行游戏的列表是由主服务器的游说。 它可以加入像其他房间,但只提供和更新房间列表。 PhotonNetwork插件会自动连接后加入游说。 当你加入一个房间时,将不再更新列表。

To display the list of rooms (in a lobby): 显示的房间列表

foreach (RoomInfo game  in PhotonNetwork.GetRoomList())
{
GUILayout.Label(game.name +  " " + game.playerCount +  "/" + game.maxPlayers);
}

Alternatively, the game can use random matchmaking: It will try to join any room and fail if none has room for another player. In that case: Create a room without name and wait until other players join it randomly.

另外,游戏可以使用随机配对:它将尝试加入任何房间,失败如果没有房间另一个玩家。 在这种情况下:创建一个没有名字的房间,等待其他玩家加入随机。

Advanced Matchmaking & Room Properties

Fully random matchmaking is not always something players enjoy. Sometimes you just want to play a certain map or just two versus two.

完全随机配对并不总是玩家喜欢的事情。 有时候你只是想扮演一个特定的地图或两个和两个。

In Photon Cloud and Loadbalancing, you can set arbitrary room properties and filter for those in JoinRandom.

在Photon云和负载平衡,可以设置任意空间属性和过滤的加入随机。

Room Properties and the Lobby

Room properties are synced to all players in the room and can be useful to keep track of the current map, round, starttime, etc. They are handled as Hashtable with string keys. Preferably short keys.

房间属性是同步到所有玩家的房间,可能是有用的跟踪当前地图,圆的、开始时间等。它们作为散列表处理字符串键。 最好是短键

You can forward selected properties to the lobby, too. This makes them available for listing them and for random matchmaking, too. Not all room properties are interesting in the lobby, so you define the set of properties for the lobby on room creation.

你也可以选择属性转发给大堂。 这使得它们用于清单,随机配对,。 并不是所有房间属性是有趣的大厅里,所以你定义一组属性的游说创造空间。
Hashtable roomProps =  new Hashtable() { {  "map", 1 } };
string[] roomPropsInLobby = {  "map""ai" };
RoomOptions roomOptions =  new RoomOptions() { customRoomProperties = roomProps, customRoomPropertiesForLobby = roomPropsInLobby }
CreateRoom(roomName, roomOptions, TypedLobby.Default)

Note that "ai" is not a key in the room-properties yet. It won't show up in the lobby until it's set in the game via Room.SetCustomProperties(). When you change the values for "map" or "ai", they will be updated in the lobby with a short delay, too.

请注意,“人工智能”还没有room-properties的关键。 它不会出现在大厅里,直到它设置在游戏中通过Room.SetCustomProperties()。 当你改变的值“地图”或“人工智能”,他们将在大堂与短的延迟更新,。

Keep the list short to make sure performance doesn't suffer from loading the list.

保持短列表,以确保从加载列表中性能不受影响。

Filtering Room Properties in Join Random

过滤室中加入随机属性

In JoinRandom, you could pass a Hashtable with expected room properties and max player value. These work as filters when the server selects a "fitting" room for you.

在JoinRandom,你可以通过一个Hashtable预期空间属性和马克斯玩家的价值。 这些工作过滤器当服务器为你选择一个“合适”的房间。
Hashtable expectedCustomRoomProperties =  new Hashtable() { {  "map", 1 } };
JoinRandomRoom(expectedCustomRoomProperties, 4);

If you pass more filter properties, chances are lower that a room matches them. Better limit the options.

如果你通过更多的过滤特性,一个房间比赛的机会较低。 更好的限制选项。

Make sure you never filter for properties that are not known to the lobby (see above).

确保你永远不会过滤属性不知道大堂(见上图)。

MonoBehaviour Callbacks 回调

PUN uses several callbacks to let your game know about state changes like “connected” or “joined a game”. All you have to do is implement the fitting method in any MonoBehaviour and it gets called when the event happens.

双关使用多个回调,让你的游戏知道状态改变像“连接”或“加入游戏”。 所有你要做的就是实现拟合方法在任何MonoBehaviour事件发生时被调用。

To get a good overview of available callbacks, take a look at the class Photon.PunBehaviour. If you make your script a PunBehaviour (instead of a MonoBehaviour), you can override individual callbacks easily. If you begin to type "override", your coding IDE should provide you a list of callbacks, so they are easy to find while coding, too.

得到很好地概述可用的回调,看看Photon.PunBehaviour的类。 如果你使你的脚本PunBehaviour(而不是MonoBehaviour),您可以重写个人容易回调。 如果你开始“覆盖”类型,编码IDE应该提供你一个回调函数的列表,所以它们很容易找到编码时,。

This covers the basics of setting up game rooms. Next up is actual communication in games.

这涵盖了基本的设置游戏房间。 接下来是实际沟通在游戏中。

Sending messages in rooms 发送消息在房间

Inside a room you are able to send network messages to other connected players. Furthermore you are able to send buffered messages that will also be sent to players that connect in the future (for spawning your player for instance).

在一个房间你可以发送网络消息到其他玩家连接。 而且你能够发送缓冲,也会将消息发送到玩家连接未来的(例如产卵你的玩家)。

Sending messages can be done using two methods. Either RPCs or by using the PhotonView property OnSerializePhotonView. There is more network interaction though. You can listen for callbacks for certain network events (e.g. OnPhotonInstantiate, OnPhotonPlayerConnected) and you can trigger some of these events (PhotonNetwork.Instantiate). Don’t worry if you’re confused by the last paragraph, next up we’ll explain for each of these subjects.

发送消息可以使用两种方法。 rpc或通过使用OnSerializePhotonView PhotonView属性。 有更多的网络交互。 可以为某些网络监听回调事件(例如OnPhotonInstantiate OnPhotonPlayerConnected)可以触发一些事件(PhotonNetwork.Instantiate)。 不要担心如果你困惑最后一段,接下来我们将解释这些科目。

Using Groups in PUN 用组

Groups are not synchronized when they are changed on any PhotonView. It's up to the developer to keep photonviews in the same groups on all clients, if that's needed. Using different group numbers for the same photonview on several clients will cause some inconsistent behaviour.组不同步时在任何PhotonView改变。 由开发人员保持photonviews在同一组对所有客户,如果这是必要的。 使用不同组数据相同的photonview几个客户会导致一些不一致的行为。

Some network messages are checked for their receiver group at the receiver side only, namely: 一些网络消息检查接收器组在接收机端,即:

  • RPCS that are targeted to a single player (or MasterClient) rpc是针对一个单一的玩家(或MasterClient)
  • RPCS that are buffered (AllBuffered/OthersBuffered). rpc缓冲(AllBuffered / OthersBuffered)。
  • This includes PhotonNetwork.Instantiate (as it is buffered). 这包括PhotonNetwork。 实例化(缓冲)。

Technical reason for this: the photon server only supports interestgroups for messages that are not cached and are not targetted at sepcific actor(s). This might change in the future.

技术原因:Photon服务器只支持服务的消息不缓存,不针对摘要演员(s)。 这在未来可能会改变。

PhotonView

PhotonView is a script component that is used to send messages (RPCs and OnSerializePhotonView). You need to attach the PhotonView to your games gameobjects. Note that the PhotonView is very similar to Unity’s NetworkView.

PhotonView是一个脚本组件,用于发送消息(rpc和OnSerializePhotonView)。 你需要把PhotonView gameobjects游戏。 注意,PhotonView非常类似于Unity的NetworkView。

At all times, you need at least one PhotonView in your game in order to send messages and optionally instantiate/allocate other PhotonViews.

在任何时候,你需要至少一个PhotonView在你的游戏和其他可选地实例化/分配PhotonViews发送消息。

To add a PhotonView to a gameobject, simply select a gameobject and use: “Components/Miscellaneous/Photon View”.

添加一个PhotonView gameobject,简单地选择一个gameobject和使用:“组件/杂项/Photon视图”。
Unity+ Photon服务器实时对战游戏——主服务器和大厅(四)
Photon View

Observe Transform 观察变换

If you attach a Transform to a PhotonView’s Observe property, you can choose to sync Position, Rotation and Scale or a combination of those across the players. This can be a great help for prototyping or smaller games. Note: A change to any observed value will send out all observed values - not just the single value that’s changed. Also, updates are not smoothed or interpolated.

如果你连接一个变换PhotonView的观察属性,您可以选择同步位置,旋转和规模或那些在玩家的组合。 这是一个伟大的帮助原型或小游戏。 注意:更改任何观察到的值将发送所有观测值——不仅仅是单值的改变。 同时,更新不平滑或窜改。

Observe MonoBehaviour

A PhotonView can be set to observe a MonoBehaviour. In this case, the script’s OnPhotonSerializeView method will be called. This method is called for writing an object’s state and for reading it, depending on whether the script is controlled by the local player.

一个MonoBehaviour PhotonView可以观察。 在这种情况下,脚本OnPhotonSerializeView方法将被调用。 调用此方法为写作对象的状态和阅读它,取决于该脚本是由当地的玩家。

The simple code below shows how to add character state synchronization with just a few lines of code more:

下面的简单的代码显示了如何添加角色状态同步只有几行代码:
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
//We own this player: send the others our data
stream.SendNext((int)controllerScript._characterState);
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
}
else
{
//Network player, receive data
controllerScript._characterState = (CharacterState)( int)stream.ReceiveNext();
correctPlayerPos = (Vector3)stream.ReceiveNext();
correctPlayerRot = (Quaternion)stream.ReceiveNext();
}
}

If you send something “ReliableDeltaCompressed”, make sure to always write data to the stream in the same order. If you write no data to the PhotonStream, the update is not sent. This can be useful in pauses. Now on, to yet another way to communicate: RPCs.

如果你发送一些“ReliableDeltaCompressed”,确保总是在相同的顺序向流写入数据。 如果你写PhotonStream没有数据,更新不发送。 这可能是有用的在停顿了一下。 现在,另一种方法来沟通:rpc。