您现在的位置是:首页 >技术杂谈 >(一)PUN 2基本介绍网站首页技术杂谈

(一)PUN 2基本介绍

林枫依依 2024-06-17 10:14:45
简介(一)PUN 2基本介绍

一、开始

(一)基本简介

1.简介

Photon Unity Networking (PUN) 是一个用于多人游戏的 Unity 包。灵活的配对让您的玩家进入可以通过网络同步对象的房间。 RPC、自定义属性或“低级别”光子事件只是其中的一些功能。快速且(可选)可靠的通信是通过专用的 Photon 服务器完成的,因此客户端不需要一对一连接。

2.PUN的结构

PUN封装了三层API:

(1)最高级别是 PUN 代码,它实现了 Unity 特定的功能,如网络对象、RPC 等;

(2)第二层包含与 Photon 服务器一起工作、进行匹配、回调等的逻辑。这是实时 API。这已经可以单独使用了。您会注意到 PUN 和 Realtime API(又名 LoadBalancing API)之间有很多主题重叠,但这很好;

(3)最低层由 DLL 文件组成,其中包含反序列化、协议等。

3.连接和回调

ConnectUsingSettings: 让您立即上线:它从 PhotonServerSettings 资产中获取所有重要设置,然后您就可以使用了。

PhotonNetwork.ConnectUsingSettings();

PUN 使用回调让您知道客户端何时建立连接、加入房间等。

例如:IConnectionCallbacks.OnConnectedToMaster。

为了方便,PUN 有 MonoBehaviourPunCallbacks MonoBehaviour。它实现了重要的回调接口并自动注册自己,因此您可以继承它并覆盖特定的回调方法。

// ...
public class YourClass : MonoBehaviourPunCallbacks
{
    // ...
    public override void OnConnectedToMaster()
    {
        Debug.Log("OnConnectedToMaster() was called by PUN.");
        PhotonNetwork.JoinRandomRoom();
    }
    // ...
}
// ...

或者在任何类中实现 IConnectionCallbacks 并通过 PhotonNetwork.AddCallbackTarget 注册回调实例。 

4.Matchmaking

 在 OnConnectedToMaster 中,您可以尝试加入现有房间或创建自己的房间。以下代码片段显示了启动或加入游戏的可能方法调用。

// 加入房间“someRoom”
PhotonNetwork.JoinRoom("someRoom");
//如果“someRoom”不存在、关闭或已满则失败。错误回调:IMatchmakingCallbacks.OnJoinRoomFailed
// 尝试加入任何随机游戏:
PhotonNetwork.JoinRandomRoom();
//如果没有打开的游戏则失败。错误回调:IMatchmakingCallbacks.OnJoinRandomFailed
// 创建这个房间。
PhotonNetwork.CreateRoom("MyMatch");
// 如果“MyMatch”房间已经存在则失败:IMatchmakingCallbacks.OnCreateRoomFailed

当朋友们想一起玩并且想在 PUN 之外进行交流时(例如通过 Photon Chat、Facebook),他们可以编一个房间名称并使用 JoinOrCreateRoom。如果没有其他人应该匹配到这个房间,请将其设置为不可见以进行匹配:

RoomOptions roomOptions = new RoomOptions();
roomOptions.IsVisible = false;
roomOptions.MaxPlayers = 4;
PhotonNetwork.JoinOrCreateRoom(nameEveryFriendKnows, roomOptions, TypedLobby.Default);

使用 JoinOrCreateRoom,房间是按需创建的,所以谁先创建并不重要。如果已满,则会调用 IMatchmakingCallbacks.OnJoinRoomFailed(如果您在某处实施并注册了它)。

 5.游戏逻辑

游戏对象可以用 PhotonView 组件实例化为“网络游戏对象”。它标识对象和所有者(或控制器)。控制的玩家更新其他所有人。

通常,您会将 PhotonView 添加到预制件,为其选择 Observed 组件并使用 PhotonNetwork.Instantiate 创建实例。

PhotonView 的观察组件负责每秒多次写入(和读取)网络对象的状态。为此,脚本必须实现 IPunObservable,它定义了 OnPhotonSerializeView。它看起来像这样:

// used as Observed component in a PhotonView, this only reads/writes the position
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
    if (stream.IsWriting)
    {
        Vector3 pos = transform.localPosition;
        stream.Serialize(ref pos);
    }
    else
    {
        Vector3 pos = Vector3.zero;
        stream.Serialize(ref pos);  // pos gets filled-in. must be used somewhere
    }
}

客户端可以对特定的网络对象进行远程过程调用,以应对不常发生的任何事情:

// defining a method that can be called by other clients:
[PunRPC]
public void OnAwakeRPC(byte myParameter)
{
    //Debug.Log(string.Format("RPC: 'OnAwakeRPC' Parameter: {0} PhotonView: {1}", myParameter, this.photonView));
}
// calling the RPC somewhere else
photonView.RPC("OnAwakeRPC", RpcTarget.All, (byte)1);

独立于 GameObjects,您还可以发送自己的事件:

PhotonNetwork.RaiseEvent(eventCode, eventContent, raiseEventOptions, SendOptions.SendReliable);

(二)功能概述

1.托管

(1)云端或本地

PUN 客户端连接到 Photon Cloud 或您自己的 Photon 服务器。即使您计划托管自己的服务器,Photon Cloud 也是一个很好的起点。

(2)Best region

Photon Cloud 托管在世界许多地区,以分发玩家并保持低延迟。 PUN 客户端动态检查可用服务器并自动选择最佳服务器。客户端将坚持该区域,除非延迟变得更糟。当区域列表在连接时发生变化时,PUN 也会重新评估所有区域。全自动。
“最佳区域”选项不是确定性的。有时,由于变化很小或 ping 计算完全相同,它可能是“随机的”。

从理论上讲,您可以:
从同一设备到多个区域具有完全相同的 ping。所以它是随机的,如果你最终在连接到同一网络的客户端上有不同的区域。
连接到同一网络的不同设备上同一区域的不同 ping 值(或同一设备上的不同重试)。

例如,在“us”和“usw”(或“ru”和“rue”)的情况下,您可以使用在线区域白名单来选择您想要的区域并删除其他区域或连接到明确的地区。
要调试,请将日志记录级别设置为“信息”并清除“当前最佳区域”(在双关语中:PhotonNetwork.BestRegionSummaryInPreferences = null)。查看详细信息或通过邮件将日志发送给我们。

(3)Udp、Tcp 和 WebSocket

PUN 支持多种传输层协议,这使其与大多数平台兼容。默认协议是 UDP,上面有一个可靠性协议。这是快速和灵活的。另一方面,WebSockets 在某些平台上用作唯一受支持的协议(例如 WebGL 导出)。

2.General

(1)Unity Integration

PUN 与 Unity 紧密集成。它扩展了编辑器,利用了检查器并提供了 PhotonView 组件来使游戏对象轻松联网。

(2)按 GameVersion 进行版本控制

在 Photon Cloud 中,GameVersion 字符串用作将构建(和玩家)彼此隔离的简单方法,而无需更改 AppId。在对网络逻辑进行重大更改时更改 GameVersion 以使不同版本的玩家分开。 PUN 会将其 PunVersion 字符串附加到您设置的 GameVersion 中,以减轻 PUN 版本之间潜在的不兼容性。因此,您的游戏版本“1.0”变为“1.0_2.xy”。

(3)验证

Photon 使用一个非常简单的 REST API 来集成您的作品应该使用的任何社区后端。通过外部身份验证,您可以使用用户帐户、获取用户 ID 和用户的任意值。如果需要,您还可以阻止用户连接。

(4)回调

PhotonNetwork 提供多个回调让您的游戏了解状态变化,例如“已连接”或“加入游戏”。 PUN 2 在接口中组织回调(出于性能原因),任何实现这些回调的类都必须通过 PhotonNetwork.AddCallbackTarget() 进行注册。
或者,您的脚本可以扩展 MonoBehaviourPunCallbacks,这使您能够单独覆盖每个回调方法。在这种情况下,您不必调用基本实现。

public class MyClass : MonoBehaviourPunCallbacks
{
//...
    public override void OnJoinedRoom()
    {
        Debug.Log(string.Format("OnJoinedRoom() called by PUN: {0}", PhotonNetwork.CurrentRoom.Name));
    }

3.匹配

(1)随机匹配

Photon 的配对方法非常受客户驱动且灵活。通常,服务器根据客户端的请求通过 PhotonNetwork.JoinRandomRoom() 选择一个合适的随机房间。可以使用各种过滤选项来缩小选择范围。有关配对的更多信息,请参阅我们的“配对指南”。

(2)大厅和房间列表

大厅可用于将房间组织成各种列表。客户可以加入大厅以获取列表和更新。所谓的“SQL Lobby”支持具有非常灵活的“WHERE”过滤的查询。或者,客户端可以向服务器查询列表的子集,以显示预先过滤的选择。

(3)房间选择

当客户创建房间时,他们可以定义新房间的一些行为。当然,可以定义最大玩家数量。当设置为不可见时,配对将忽略房间,只有知道房间名称的用户才能加入。您可以共享玩家的用户 ID,定义用户在断开连接后在房间列表中停留的时间等等。

(4)自定义匹配

房间的自定义属性可用于定义和共享您自己的值集。键和值通过哈希表设置。这可以在游戏中使用,也可以用于配对。只需定义哪些属性键应该在配对中可用。

(5)Slot Reservation

当以团队或聚会的形式进行游戏时,玩家通常希望团结在一起。 Photon 通过“预期玩家”支持这一点:也将加入房间的用户列表。 Photon 的配对为每个“预期”玩家保留一项运动。

4.游戏中

(1)网络对象

可以使用 PhotonView 组件将通用游戏对象转换为网络对象。 PhotonView 通过网络识别对象并用于同步它的状态。通常,PhotonView 会附加到在运行时实例化的预制件。通常每个玩家都有自己的对象来控制。
要将 PhotonView 添加到 GameObject,只需选择一个 GameObject 并使用:“Components/Miscellaneous/Photon View”。

(2)消息

进入房间后,客户可以向其他玩家或选定的玩家发送消息。
除了“低级别”通用事件(参见:RaiseEvent),PUN 有两个特定的消息传递功能:RPC 是所有玩家在特定网络对象上执行的方法调用,其次,PhotonView 可以观察脚本以同步该对象的值(位置、健康等)。观察到的脚本需要实现OnSerializePhotonView。
在需要的地方,消息可以在服务器上缓冲,服务器也会将它们发送给稍后加入的玩家。例如,这用于生成角色。

(3)Mecanim(Animator)同步

PUN 提供了一个组件来自动同步角色的动画状态。

(4)Synchronized Timestamp

每当客户端连接到 Photon 服务器时,它都会同步一个滞后校正时间戳。这可以在一个房间中使用(因为所有玩家都连接到同一个游戏服务器)以同步事件的时间。

(5)自定义属性

Photon Realtime 的自定义属性是一种同步任意值的方法。它们被组织在一个简单的哈希表中,并与房间或个别玩家相关。

5.游戏中进阶

(1)比较和交换 (CAS)

由于每个人都可以设置任何自定义属性,因此游戏逻辑可能会遇到并发问题。这可以通过 CAS 解决:只有当服务器的当前值符合条件时,才会设置新值。简而言之:当每个人都告诉服务器将值“从 1 更改为 X”时,这只会发生一次。

(2)Scene PhotonViews

默认情况下,联网对象与实例化它们的玩家具有相同的生命周期。如果玩家离开,物品就会被清理干净。场景 PhotonViews 可以在加载场景后实例化,但只要房间存在,它们就会留在房间里。当然,加载场景的联网对象也不受玩家生命周期的限制。

(3)多个场景中的场景 PhotonViews

如果场景是附加加载的,并且这些场景具有场景网络对象,请确保设置 PunSceneSettingsFile scriptableObject 资产(在 PhotonUnityNetworking/Pun/code/Editor/ 下的项目资产中)并为每个场景定义最小视图 ID 以分配:这将保证场景联网对象视图 ID 在您添加加载场景时不会发生冲突。

(4)对象控制转移

默认情况下,网络对象由实例化它的客户端控制。通过所有权转移,玩家可以请求或移交游戏对象的控制权。这改变了哪个客户端正在发送更新(而其他客户端使用并应用它们)。

(5)Interest Groups

Photon Realtime 的兴趣组(由 PUN 包装)可用于组织客户端获取哪些事件。根据您的逻辑,客户端订阅组并将事件发送到目标组。这可以用于基本的兴趣管理系统。

(6)自定义类型序列化

Photon 使您能够为您可能希望通过网络发送的任何类型定义自己的反序列化代码。这极大地简化了您通过网络发送数据的方式(以少量开销为代价)。

(7)WebHooks 和持久数据策略

要将 Photon 服务器与其他服务和您自己的服务连接起来,它使用 WebHooks 的概念。几个挂钩是预定义的,可用于更新基于 REST 的外部服务。

(8)回合制游戏

房间的另外两个选项对于回合制游戏很重要: PlayerTTL 定义了断开连接后玩家在房间中保持“不活动”的时间。 RoomTTL 定义房间中所有玩家断开连接后房间存在的时间。这样,您可以为重新加入的玩家保留房间和玩家位置。

6.性能选项

(1)联营支持

PUN 允许您对所有实例化和销毁的网络对象使用一个简单的池实现。虽然这在某些类型的游戏中并不常见,但在其他游戏中可以节省性能。

(2)缓存

除了使用池之外,PUN 还可以缓存加载的资源以实例化预制件(进入网络对象)。这减少了以内存为代价的垃圾回收。

(3)SendRate/SendRateOnSerialize 发送速率

PUN 控制联网对象写入(和读取)更新的速率。将更新放入要发送的消息的速率可以独立于此设置。

(三)设置和连接

Photon Unity Networking (PUN) 非常容易设置。将 PUN 导入到新项目中,将弹出 PUN 向导。或者它在菜单中:“Window”,“Photon Unity Networking”。

通过输入电子邮件注册一个新的(免费的)Photon Cloud 帐户,或从仪表板复制并粘贴现有的 appid。完毕。
如果您想自己托管 Photon 服务器,请单击“跳过”并编辑 PhotonServerSettings,如下所述。

 1.Photon Server 设置

该向导将一个 PhotonServerSettings 文件添加到您的项目以存储配置,该配置主要由 ConnectUsingSettings 使用。您可以设置与 Photon Cloud 或自托管服务器的连接并更改其他常见设置。

可以设置appid、Photon Cloud Region、游戏版本等。在大多数情况下,默认设置就可以了。 

(1)配置参数

AppId Realtime, Chat and Voice
Photon Cloud 使用 AppId 来识别每个标题。 PUN 使用实时应用程序 ID 进行连接。它也适用于 Photon Chat 和 Voice,如果您使用这些功能,它们都需要自己的 App Id。

App Version
在 PUN 中,应用版本是游戏版本的一部分。具有不同游戏版本值的客户端彼此分开。 PUN 将其 PunVersion 字符串添加到此值,以减轻不同 PUN 版本之间潜在的不兼容性。
Use Name Server
当连接到 Photon Server v4 实例时,客户端直接连接到主服务器,而不是名称服务器。仅在您自己托管 Photon 时取消选中此选项。有关更多详细信息,请参见此处。

Dev Region

从 PUN v2.17 开始,当您使用 PhotonNetwork.ConnectUsingSettings() 进行连接时,“开发区域”仅在 Unity 编辑器和“开发”构建中使用。您可以通过简单地删除该值来禁用 Unity Editor 和“Development Build”中的“Dev Region”。

Fixed Region

连接云端时,PUN会默认选择最佳区域。如果您想连接到特定区域,请在此处输入区域代码,最佳区域选择将关闭。

Server

当托管您自己的 Photon 服务器时,此选项最相关。为此,请获取 Photon Server SDK。
确保您的客户可以到达输入的地址。它可以是公共的静态 IP、主机名或您的客户使用的网络中的任何地址。
如果你为 iOS 开发游戏,你可以考虑阅读“pun and ipv6”和“how to setup photon server for ipv6”。
设置正确后,您可以在代码中调用 PhotonNetwork.ConnectUsingSettings()。

 Port and Protocol

Photon 被构建为在一个会话期间使用多个服务器。此处输入的端口是第一个连接的服务器之一。这可以是主服务器或名称服务器。该端口还取决于所选协议。
如果连接到 Photon Cloud,请将此值保留为 0。否则,请查找 Photon 使用的标准端口。
协议的默认值是(可靠的)UDP,但 Photon 支持 TCP 和 WebSockets。 PUN 客户端将在 WebGL 导出中自动使用安全 WebSockets。
我们建议您坚持使用 UDP。

Enable Lobby Statistics

要从服务器获取大厅统计信息,应该选中此项。有关详细信息,请参阅“应用程序和大厅统计信息”页面。

Network Logging

这控制了较低级别的光子代码的日志记录。除非需要,这应该坚持错误设置。

Enable Support Logger

当您需要跟踪连接、配对或房间中发生的事情时,这是一个有用的设置。选中后,我们的脚本将注册回调并记录重要信息以帮助调试您的游戏。

Run in Background

这会设置同名的 Unity 设置。

RPC List

“远程过程调用”使您能够在房间中的其他客户端上调用方法。 PUN 在 PhotonServerSettings 中保留了这些方法的列表,并在调用 RPC 时使用每个名称的索引作为缩写。

2.自托管 Photon 服务器的配置

我们建议使用 PhotonNetwork.ConnectUsingSettings 方法连接并在连接前相应地调整 PhotonServerSettings,无论是在编译时在 Unity Editor 中还是在运行时通过代码(更改 PhotonNetwork.PhotonServerSettings.AppSettings)。我们还推荐使用 Photon Server v5。

(1)Photon Server v5

按照 NameServer.json 中的配置清除或设置固定区域。将“服务器”设置为您的 Photon 服务器的 IP 或主机名。它必须在您的客户端可以访问的网络中。如果客户端是在同一台机器上的独立构建,则可以使用“localhost”或 127.0.0.1。您可以将端口号设置为 0,客户端将根据协议选择默认端口号。否则,输入端口:例如默认 UDP 为 5058,默认 WSS 为 19093,等等(或者如果您在 PhotonServer.config 中更改了名称服务器应用程序的自定义端口)。请在此处查看每个协议和服务器的默认端口列表。

使用 Photon Server (OnPremises) 时,您需要知道与 Photon Cloud 存在一些差异。这些都列在这里。 

(2)Photon Server v4

取消选中“使用名称服务器”,因为 Photon Server v4 SDK 不包含此服务。清除固定区域。将“服务器”设置为您的 Photon 服务器的 IP 或主机名。它必须在您的客户端可以访问的网络中。如果客户端是在同一台机器上的独立构建,则可以使用“localhost”或 127.0.0.1。输入端口:默认 UDP 协议的 5055(如果您在 PhotonServer.config 中更改了 MasterServer 应用程序的自定义端口)。请在此处查看每个协议和服务器的默认端口列表。

 使用 Photon 服务器 (OnPremises) 时,需要进行一些显着调整:
如果连接到 Photon Server v4,请在连接前将序列化协议设置为 1.6 版(因为 1.8 与该服务器版本不兼容):PhotonNetwork.NetworkingClient.SerializationProtocol = SerializationProtocol.GpBinaryV16;。
即使您不对用户进行身份验证,客户也需要设置唯一的 UserId。例如,为每个设备生成并保存一个 GUID。
GameVersion / AppVersion 不用于创建单独的虚拟 AppId。

(四)C# 回调

C# SDK 提供了您可以在您的类中实现的回调接口:

Photon Realtime C# SDK 回调接口:

IConnectionCallbacks:连接相关的回调。

IInRoomCallbacks:房间内发生的回调。

ILobbyCallbacks:大厅相关回调。

IMatchmakingCallbacks:匹配相关的回调。

IOnEventCallback:任何接收到的事件的单个回调。这与 C# 事件LoadBalancingClient.EventReceived“等效”。

IWebRpcCallback:用于接收 WebRPC 操作响应的单个回调。

IOnErrorInfoCallback:用于接收 ErrorInfo 事件的单个回调。

PUN 2 特定的回调接口:

 除了 Photon Realtime C# 之外,PUN 2 添加了一些专用接口。我们将根据它们的“范围”和处理方式将它们分为两组:

通用回调接口:

IPunInstantiateMagicCallback:实例化 PUN 预制件的单个回调。

IPunOwnershipCallbacks:PUN 所有权转移回调。

PhotonView 回调接口:

 IPunObservable:PhotonView 序列化回调。

IOnPhotonViewPreNetDestroy:PhotonView 联网对象销毁之前的 OnPreNetDestroy() 回调。

IOnPhotonViewControllerChange:控制器更改时的 OnControllerChange() 回调。

IOnPhotonViewOwnerChange:所有者更改时的 OnOwnerChange() 回调。

除 IPunInstantiateMagicCallback 外,所有实现任何 Photon Realtime 或 General PUN 2 回调接口的类都必须注册和注销。调用 PhotonNetwork.AddCallbackTarget(this) 和 PhotonNetwork.RemoveCallbackTarget(this)。 

除 IPunObservable 外,所有实现任何 PhotonView 回调接口的类都必须注册和注销。调用 photonView.AddCallbackTarget(this) 和 photonView.RemoveCallbackTarget(this)。 IPunObservable 接口通过检查器处理,不是添加/删除系统的一部分。

您可以为每个类实现一个或多个接口。您还可以通过多个类实现相同的接口。付出的代价是实现这些接口的类可能变得太长或有未使用的方法。

例如,在 Unity 中,您可以使用 MonoBehaviour 的 OnEnable() 和 OnDisable() 或 Start()/Awake() 和 OnDestroy()。

实现这些接口是可选的,但建议这样做,因为我们认为它可以使您的代码更具可读性和可维护性。它还通过提供执行某些逻辑的准确时间,使 Photon 流和状态更易于管理。其他替代方案可能需要使用状态标志字段、轮询以检查客户端网络状态或订阅所有网络客户端的状态更改或接收到的事件或操作响应。这需要对某些内部结构或低级 Photon 细节有深入的了解,您可以避免这些并专注于您的游戏。

如果未处理(未捕获)的异常发生在已实现接口的回调方法之一中,则不会调用同一接口、相同签名且尚未调用的所有其他已实现方法。这是因为我们按照注册顺序在循环中调用相同签名的已实现接口回调方法(如果您在 MonoBehaviour 方法中注册,这在 Unity 中可能是随机的)。

选择接口而不是其他实现回调系统的方式的原因:

(1)确保回调的方法签名得到尊重,这是编译器在实现接口时保证的;

(2)将逻辑上相关的回调分组到一个类中;

(3)与提供回调的其他方法相比,它具有更少的垃圾开销并避免内存泄漏。

如果您碰巧有一个方法具有与回调接口方法之一完全相同的签名,或者您希望隐藏回调方法(除非进行了强制转换),您可以选择显式接口实现。

继承自 MonoBehaviourPunCallbacks 类是实现 PUN2 回调最简单和最快的方法:

(1)它是一个 MonoBehaviour,允许您有选择地覆盖您需要的回调,并且只覆盖您需要的回调;

(2)无需记住所有回调的接口,因为它实现了其中的大部分:IConnectionCallbacks、IMatchmakingCallbacks、IInRoomCallbacks、ILobbyCallbacks、IWebRpcCallback 和 IOnErrorInfoCallback;

(3)它已经代表您处理回调注册和注销(分别在 OnEnable() 和 OnDisable() 中);

(4)它扩展了 MonoBehaviourPun,如果后者附加到同一个 GameObject,它可以轻松地在属性中公开 PhotonView;

但是,您应该小心:

(1)它没有实现所有回调接口,但实现了大部分。它不实现 IOnEventCallback 或 PUN 特定的回调。 PUN2 的实用程序接口也没有实现,例如IPunTurnManagerCallbacks;

(2)如果你扩展 MonoBehaviourPunCallbacks 如果你覆盖 OnEnable() 和 OnDisable() 确保调用基类方法;

(3)如果组件未附加到与 PhotonView 相同的游戏对象,则 MonoBehaviourPunCallbacks.photonView 将为 null(且无用)。

(五)版本迁移说明

PUN 2 在一个包中聚合了许多重大更改和更新,但总体用法与您所知的 PUN 类似。它是一个独立于 PUN 1.x 的包,因此您可以选择何时更新。此外,您可以随时返回。
如果您使用 PUN Plus (v1.x) 并想更新到 PUN 2,请将您现有的 AppId 与 PUN 2 免费包一起使用。所有好处都会结转。
要更新,最好完全删除 PUN 并全新安装 PUN 2 以进行必要的 API 和逻辑更改。下面,您会发现最大的变化,但列表可能不完整。

1.概述

(1)PUN 2 现在包含并使用了 Realtime API,它不太特定于 Unity。

(2)这两个层有两个不同的命名空间:Photon.Pun 和 Photon.Realtime。

(3)最佳区域选择和回调系统现在在 Realtime API 中完成。地区枚举不见了。

(4)只有 ConnectUsingSettings() 正在使用 photonserversettings。

(5)由于各种原因,许多回调、方法和字段被重命名。

(6)对于回调,一个类必须实现一个接口并将自己注册为感兴趣的。

(7)MonoBehaviourPunCallbacks 实现大多数回调。继承此类并根据需要覆盖。在 OnEnable 和 OnDisable 中调用 base。

2.API 变更

(1)PhotonNetwork.autoJoinLobby 和 ServerSettings.JoinLobby 不见了。除非你需要一个大厅,否则不要加入他们。

(2)PhotonNetwork.GetRoomList() 消失了。您从 ILobbyCallbacks.OnRoomListUpdate(List<RoomInfo> roomList) 回调中获取房间列表和更新。您可以选择缓存它、更新它并在需要时清除它。

(3)PhotonNetwork.Friends 不见了。您从 IMatchmakingCallbacks.OnFriendListUpdate(List<FriendInfo> friendList) 回调中获取好友列表。您可以选择缓存它、更新它并在需要时清除它。

(4)PhotonNetwork.LobbyStatistics 不见了。启用后,您可以从 ILobbyCallbacks.OnLobbyStatisticsUpdate(List<TypedLobbyInfo> lobbyStatistics) 回调中获取大厅统计列表。您可以选择缓存它、更新它并在需要时清除它。

(5)PhotonNetwork.connecting 不见了。

(6)PhotonNetwork.connectionState 消失了。

(7)PhotonNetwork.isNonMasterClientInRoom 不见了。

(8)PhotonNetwork.autoCleanUpPlayerObjects 不见了。在 PUN2 中,此设置不再是全局的,而是每个房间的。您可以在创建房间时通过 RoomOptions.CleanupCacheOnLeave 设置它。加入房间后,您可以通过 PhotonNetwork.CurrentRoom.AutoCleanUp 获取它。

(9)PhotonNetwork.networkingPeer 不见了。它涵盖的任务现在直接在 PhotonNetwork 类或 PhotonNetwork.NetworkingClient 中处理。

(10)PhotonNetwork.ConnectUsingSettings() 不再采用 gameVersion 参数。 Unity Editor 中 PhotonServerSettings 中的 AppVersion 参数集,AppSettings 部分用作 PhotonNetwork.GameVersion。如果你想从代码中设置 PhotonNetwork.GameVersion 你可以:

(a)在调用 PhotonNetwork.ConnectUsingSettings() 之后设置 PhotonNetwork.GameVersion
在调用 PhotonNetwork.ConnectUsingSettings() 之前设置;(b)PhotonNetwork.PhotonServerSettings.AppSettings.AppVersion;

(11)只有 ConnectUsingSettings() 正在使用 PhotonServerSettings。使用其他连接方法时,应用需要手动设置 AppId 和其他值(并且设置不会覆盖这些值)。

(12)ServerSettings.EnableLobbyStatistics 已移至 ServerSettings.AppSettings.EnableLobbyStatistics。

(13)ServerSettings.AppID 移至 ServerSettings.AppSettings.AppIdRealtime。

(14)ServerSettings.VoiceAppID 已移至 ServerSettings.AppSettings.AppIdVoice。

(15)ServerSettings.ChatAppID 已移至 ServerSettings.AppSettings.AppIdChat。

(16)ServerSettings.NetworkLogging 移至 ServerSettings.AppSettings.NetworkLogging。

(17)ServerSettings.ServerAddress 移至 ServerSettings.AppSettings.Server。

(18)ServerSettings.ServerPort 移至 ServerSettings.AppSettings.Port。

(19)ServerSettings.Protocol 移动到 ServerSettings.AppSettings.Protocol

(20)在 PUN2 中,UserId 将不再设置为 Nickname,以防前者未设置。这曾经是 PUN1 的情况。

(21)PhotonNetwork.LoadLevelAsync() 消失了。 PhotonNetwork.LoadLevel 在 PUN2 中默认和设计上始终是异步的。要获取关卡加载进度,请使用 PhotonNetwork.LevelLoadingProgress。

(22)PhotonNetwork.PhotonServerSettings.UseMyServer(server, port, app) 没有了,可以换成:

PhotonNetwork.PhotonServerSettings.AppSettings.Server = server;
PhotonNetwork.PhotonServerSettings.AppSettings.Port = port;
PhotonNetwork.PhotonServerSettings.AppSettings.RealtimeAppId = app; // either AppId or "master" or don't set anything

 3.命名空间变更

(1)RoomOptions 现在位于 Photon.Realtime 命名空间中

(2)AuthenticationValues 现在位于 Photon.Realtime 命名空间中

(3)RoomInfo 现在位于 Photon.Realtime 命名空间中

(4)Room 现在位于 Photon.Realtime 命名空间中

(5)FriendInfo 现在位于 Photon.Realtime 命名空间中

(6)TypedLobbyInfo 现在位于 Photon.Realtime 命名空间中

(7)TypedLobby 现在位于 Photon.Realtime 命名空间中

(8)LobbyType 现在位于 Photon.Realtime 命名空间中

(9)RaiseEventOptions 现在位于 Photon.Realtime 命名空间中

(10)WebRpcResponse 现在位于 Photon.Realtime 命名空间中

(11)IPunObservable 现在是 Photon.Pun 命名空间

4.重命名

公共字段和属性:

  1. photonView.isMine 现在是 photonView.IsMine
  2. photonView.owner 现在是 photonView.Owner
  3. photonView.instantiationData 现在是 photonView.InstantiationData
  4. PhotonNetwork.automaticallySyncScene 现在是 PhotonNetwork.AutomaticallySyncScene
  5. PhotonNetwork.gameVersion 现在是 PhotonNetwork.GameVersion
  6. PhotonNetwork.masterClient 现在是 PhotonNetwork.MasterClient
  7. PhotonNetwork.isMasterClient 现在是 PhotonNetwork.IsMasterClient
  8. PhotonNetwork.inRoom 现在是 PhotonNetwork.InRoom
  9. PhotonNetwork.isMessageQueueRunning 现在是 PhotonNetwork.IsMessageQueueRunning
  10. PhotonNetwork.offlineMode 现在是 PhotonNetwork.OfflineMode
  11. PhotonNetwork.countOfPlayersOnMaster 现在是 PhotonNetwork.CountOfPlayersOnMaster
  12. PhotonNetwork.countOfPlayersInRooms 现在是 PhotonNetwork.CountOfPlayersInRooms
  13. PhotonNetwork.countOfPlayers 现在是 PhotonNetwork.CountOfPlayers
  14. PhotonNetwork.countOfRooms 现在是 PhotonNetwork.CountOfRooms
  15. PhotonNetwork.sendRate 现在是 PhotonNetwork.SendRate
  16. PhotonNetwork.time 现在是 PhotonNetwork.Time
  17. PhotonNetwork.playerList 现在是 PhotonNetwork.PlayerList
  18. PhotonNetwork.precisionForVectorSynchronization 现在是 PhotonNetwork.PrecisionForVectorSynchronization
  19. PhotonNetwork.precisionForQuaternionSynchronization 现在是 PhotonNetwork.PrecisionForQuaternionSynchronization
  20. PhotonNetwork.precisionForFloatSynchronization 现在是 PhotonNetwork.PrecisionForFloatSynchronization
  21. PhotonStream.isWriting 现在是 PhotonStream.IsWriting
  22. PhotonStream.isReading 现在是 PhotonStream.IsReading
  23. RoomOptions.cleanUpCacheOnLeave 现在是 RoomOptions.CleanupCacheOnLeave
  24. RoomOptions.publishUserId 现在是 RoomOptions.PublishUserId
  25. RoomOptions.suppressRoomEvents 现在是 RoomOptions.SuppressRoomEvents

 其他:

  1. PhotonNetwork.connected 现在是 PhotonNetwork.IsConnected
  2. PhotonNetwork.connectedAndReady 现在是 PhotonNetwork.IsConnectedAndReady
  3. PhotonNetwork.networkingPeer 现在是 PhotonNetwork.NetworkingClient
  4. PhotonNetwork.connectionStateDetailed 现在是 PhotonNetwork.NetworkClientState
  5. PhotonNetwork.playerName 现在是 PhotonNetwork.NickName
  6. PhotonNetwork.room 现在是 PhotonNetwork.CurrentRoom
  7. PhotonNetwork.lobby 现在是 PhotonNetwork.CurrentLobby
  8. PhotonNetwork.player 现在是 PhotonNetwork.LocalPlayer
  9. PhotonNetwork.insideLobby 现在是 PhotonNetwork.InLobby
  10. PhotonNetwork.otherPlayers 现在是 PhotonNetwork.PlayerListOthers
  11. PhotonNetwork.sendRateOnSerialize 现在是 PhotonNetwork.SerializationRate
  12. PhotonNetwork.versionPUN 现在是 PhotonNetwork.PunVersion
  13. PhotonTargets 枚举现在是 Photon.Pun.RpcTarget
  14. PhotonPlayer 类现在是 Photon.Realtime.Player(构造函数不再公开)
  15. PhotonPlayer.ID 现在是 Photon.Realtime.Player.ActorNumber

 5.回调变化

(1)除了 IPunInstantiateMagicCallback 之外的所有回调接口都必须注册和注销。
调用 PhotonNetwork.AddCallbackTarget(this) 和 PhotonNetwork.RemoveCallbackTarget(this)(可能分别在 OnEnable() 和 OnDisable() 中)。

(2)将 Photon.PunBehaviour 替换为 MonoBehaviourPunCallbacks。
在 MonoBehaviourPunCallbacks 的 OnEnable() 和 OnDisable() 重写中调用基类方法。

(3)PhotonNetwork.OnEventCall 消失了。
你有两个选择:
(a)使用 PhotonNetwork.NetworkingClient.EventReceived(EventData) 代替。
(b)使用 IOnEventCallback.OnEvent(EventData)。

在 PUN2 中,事件回调签名发生了变化,但您可以从 EventData 中获取所需内容。此外,事件回调将针对所有事件触发,而不仅仅是自定义事件(自定义事件代码 < 200)。 

(4)默认情况下,参与者或房间属性的设置属性不会在加入在线房间时立即对发送者/设置者客户端(设置属性的参与者)生效,这与 PUN Classic 中的情况不同。现在,发送者/设置者客户端(设置属性的参与者)将等待服务器事件 PropertiesChanged 以在本地应用/设置更改。因此,您需要等待本地客户端触发 OnPlayerPropertiesUpdate 或 OnRoomPropertiesUpdate 回调才能访问它们。新行为是由于引入了新房间选项标志 roomOptions.BroadcastPropsChangeToAll,默认设置为 true。这背后的原因是,如果我们先在本地设置属性,然后在服务器上和房间中的其他参与者发送请求,属性很容易失去同步。后者可能会失败,我们最终可能会发现发送者/设置者客户端(设置属性的参与者)的属性在本地与服务器或其他客户端上的不同。如果您想要旧行为(在将请求发送到服务器以同步它们之前在本地设置属性),请在创建房间之前将 roomOptions.BroadcastPropsChangeToAll 设置为 false。但我们强烈建议不要这样做。

(5)PUN2 不会触发 OnRoomPropertiesUpdated 或 OnPlayerPropertiesUpdated 回调,除非通过 SetProperties 调用更改它们。在 PUN2 中,当进入房间时(在创建、加入或重新加入房间之后)OnPlayerPropertiesUpdate 或 OnRoomPropertiesUpdate 回调不会被初始化属性触发。您可以通过 PhotonNetwork.CurrentRoom.CustomProperties(或 PhotonNetwork.CurrentRoom 的其他类属性,如 IsOpen、IsVisible、MaxPlayers 等)或 PhotonNetwork.LocalPlayer.CustomProperties 访问初始值。

在下表中,仅当 PUN1 和 PUN2 之间的方法签名不同时才显示方法参数:

PUN 1 (Callback)PUN 2 (Interface | Callback)
OnConnectedToPhotonIConnectionCallbacksOnConnected
OnFailedToConnectToPhoton()IConnectionCallbacksOnDisconnected(DisconnectCause)
OnConnectionFail()IConnectionCallbacksOnDisconnected(DisconnectCause)
OnDisconnectedFromPhoton()IConnectionCallbacksOnDisconnected(DisconnectCause)
OnConnectedToMasterIConnectionCallbacksOnConnectedToMaster
OnPhotonMaxCccuReached()IConnectionCallbacksOnDisconnected(DisconnectCause)
OnCustomAuthenticationFailedIConnectionCallbacksOnCustomAuthenticationFailed
OnCustomAuthenticationResponseIConnectionCallbacksOnCustomAuthenticationResponse
OnMasterClientSwitched(PhotonPlayer)IInRoomCallbacksOnMasterClientSwitched(Player)
OnPhotonPlayerConnected(PhotonPlayer)IInRoomCallbacksOnPlayerEnteredRoom(Player)
OnPhotonPlayerDisconnected(PhotonPlayer)IInRoomCallbacksOnPlayerLeftRoom(Player)
OnPhotonPlayerActivityChanged(PhotonPlayer)IInRoomCallbacksOnPlayerEnteredRoom(Player)
OnPlayerLeftRoom(Player)
OnPhotonCustomRoomPropertiesChangedIInRoomCallbacksOnRoomPropertiesUpdate
OnPhotonPlayerPropertiesChanged(object[])IInRoomCallbacksOnPlayerPropertiesUpdate(Player, Hashtable)
OnJoinedLobbyILobbyCallbacksOnJoinedLobby
OnLeftLobbyILobbyCallbacksOnLeftLobby
OnReceivedRoomListUpdate()ILobbyCallbacksOnRoomListUpdate(List<RoomInfo>)
OnLobbyStatisticsUpdate()ILobbyCallbacksOnLobbyStatisticsUpdate(List<TypedLobbyInfo>)
OnLeftRoomIMatchmakingCallbacksOnLeftRoom
OnPhotonCreateRoomFailed(object[])IMatchmakingCallbacksOnCreateRoomFailed(short, string)
OnPhotonJoinRoomFailed(object[])IMatchmakingCallbacksOnJoinRoomFailed(short, string)
OnCreatedRoomIMatchmakingCallbacksOnCreatedRoom
OnJoinedRoomIMatchmakingCallbacksOnJoinedRoom
OnPhotonRandomJoinFailed(object[])IMatchmakingCallbacksOnJoinRandomFailed(short, string)
OnUpdatedFriendList()IMatchmakingCallbacksOnFriendListUpdate(List<FriendInfo>)
-IOnEventCallbackOnEvent(EventData)
OnPhotonInstantiateIPunInstantiateMagicCallbackOnPhotonInstantiate
OnPhotonSerializeViewIPunObservableOnPhotonSerializeView
OnOwnershipRequest(object[])IPunOwnershipCallbacksOnOwnershipRequest(PhotonView, Player)
OnOwnershipTransfered(object[])IPunOwnershipCallbacksOnOwnershipTransfered(PhotonView, Player)
OnWebRpcResponseIWebRpcCallbackOnWebRpcResponse

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。