deb*_*ian 3 c# unity-game-engine photon
我在官方的Photon Server论坛上问过这个问题,但它不如这个网站那么活跃,所以可能会有人理解我在说什么,所以,如果你有时间和知识,请分享.谢谢!
来这里......
所以,我在Photon上有一个非常好的服务器工作原型和一个与服务器对话的基本Unity3D客户端.它是根据cjrgaming上的示例构建的.
客户端可以:连接,发送请求,建立和发送加密请求服务器可以:创建对等,接收操作请求,向客户端发送操作响应或事件,以及我的小增加是:如果游戏有很多操作,你不必使用一个巨大的switch case语句,而是我将操作划分为类别(Classes),并通过使用委托和字典来调用它们.
当我觉得它已经准备好发布时,我会发布一个有效的例子,但是现在,我的实际问题......(对不起,很长的帖子,我不得不解释我所知道的和迄今为止的内容):
什么是从客户端发送到服务器的实际操作?或者服务器向客户端提出的事件(所有客户端一次性?)?
起初,我认为每个操作都是游戏中特定的用户流程.例如,操作代码"1"表示玩家X想要射击玩家Y,做某事.但是,我意识到,根据字节限制,您不能将所有游戏逻辑仅放在255个操作中,而不会将其扩展为short int或其他内容.
然后我发现还有一个channelID,它可以在同一个操作代码请求上有所不同......这对我来说,操作代码不是用户流,而是客户端之间相同/类似操作的数据流和服务器,channelID可用于区分要在服务器上计算的请求操作.
然后...!我意识到(哦,假我),从客户端发送到服务器的参数,反之亦然在字典中,这增加了另一层可能的用户流.
所以..现在我想要了解一些事情,但他们只是让我更加困惑.
任何人都可以简单解释一下操作/事件/ channelID的目的吗?例如,如果你做一个小型多人游戏,你会用什么来制作用户(游戏)流,比如 - >玩家击中目标,玩家拿起世界上的物品,玩家发送消息.您是否会为每个流使用唯一的操作代码,或者您通过意义分组操作并使用通道来区分请求,或者甚至在这里,您对许多用户流使用相同的channelID,并将它们与参数中的某些ID区分开来?
希望我有任何意义.
非常感谢,至少,如果有的话,请多多帮助!
Kai*_*udi 14
1)频道是一个完全不同的主题,与区分你想要触发的不同类型的游戏逻辑无关.相反,如果操作依赖于另一个操作,则通道用于确定优先级和状态.
a)如果您发送的拍摄操作和2聊天的操作和作为客户端的网络连接是不是最好的,第一的聊天消息的那张丢失的方式,但正如你说送可靠的是,当服务器未确认时,Photon客户端将自动重新发送它,它已收到它.现在另一个聊天消息应该由Photon阻止,直到第一个成功发送,否则来自同一作者的显示的聊天消息的顺序将不再是他们已经写入的那个.现在的问题是,不仅应该阻止相同类型的操作,而且可能还有其他操作,只应在丢失的操作重复之后发送(例如"用户离开的可见结果"聊天"操作不应该显示在屏幕上,直到他最后一次聊天消息之后,他已经离开前发送了.另一方面,不是所有相同类型的操作都必须被阻止.例如,玩家可以私下与2个不同的其他用户交谈,并且当其中一个用户的一条消息没有立即通过时,则没有理由将所有消息保持到另一个消息.光子解决这个问题的方法是通道:在同一个通道中发送彼此依赖的所有操作,但在另一个通道中发送独立于它们的操作.如果现在必须重复其中一个操作,则其他通道中的操作将不会被阻止,但是同一通道中的操作将会被阻止.
b)另一种信道方式是确定优先级:信道ID越低,优先级越高.所以,如果你有一些少量的高优先级数据和其他数据的,仅具有低优先级,但可以发生在出现巨额资金,那么这将是一个好主意,用较低的发送通道上的高优先级数据信道ID.这样它仍然可以立即退出,虽然在ID较高的频道中,可能有很多数据已经排队等待发送,但尚未发送.
2)操作和事件都是消息.实际上有三种类型的消息:operationRequest,operationResponse和event.
a)客户端可以通过PhotonPeer.opCustom()向服务器发送带有特定操作代码的operationRequest.一些典型的操作,如加入和离开房间,已经通过Photon应用程序层(如Lite或LoadBalancing应用程序)的应用程序实现.如果为Photon应用程序提供了客户端API,那么此API可以提供开箱即用的opJoin()函数,它使用正确的参数将调用包装到opCustom(),就像上面提到的应用程序的客户端API一样做.
b)根据在应用程序级别上如何实现具有特定代码的操作,服务器可以向客户端发送operationResponse,从该客户端接收operationReqeust.例如,LitePeer.opJoin()将从服务器触发连接响应,但LitePeer.opRaiseEvent不会触发响应.
c)根据在应用程序级别上如何实现操作,服务器可能会也可能不会将事件发送到某些客户端.例如,LitePeer.opJoin()将触发一个join事件,该事件将被发送给该房间中的所有玩家.LitePeer.opRaiseEvent()将默认让服务器为同一房间中除发送服务器之外的所有客户端引发一个事件,即保存已传递给它的有效负载.但是,opRaiseEvent()为其调用客户端提供了指定接收客户端的可能性.
3)"玩家击中目标,玩家拿起世界上的物品,玩家发送消息"如果您需要任何特殊的服务器端逻辑,那么您将使用不同的代码将它们实现为自己的操作.如果不是这种情况,那么您将使用opRaiseEvent()发送这些信息,但是您仍然会为每个信息指定不同的eventCode.但是,operation和eventCodes旨在用于区分不同类型的信息,想聊天消息,搓一击,位置更新等,所以玩家会告诉玩家b,他已经打玩家C和玩家b告诉球员d,他已经打球员d,将都使用相同的代码.关于哪个玩家被击中的信息 - 与击中或使用哪种武器的难度相同 - 都属于操作的有效载荷.因此,您可以将播放器的玩家ID,已被击中,弹药类型以及丢失的生命能量传递给opRaiseEvent()或opCustom().
| 归档时间: |
|
| 查看次数: |
5860 次 |
| 最近记录: |