为Unity构建一个简单的在线游戏服务器

Fly*_*ast 5 multiplayer game-engine unity-game-engine

我正在尝试为我的坦克游戏2D(Unity)构建一个在线游戏服务器.在我的游戏中,将有2-4名玩家控制他们的坦克并互相争斗.

  • 我试过使用Unity网络,它不适合我的游戏,因为我们必须选择房间里的1个玩家成为"服务器",这对我未来的发展来说并不是很灵活(例如当"服务器"退出,我必须做很多工作来保持其他玩家之间的联系).

  • 然后我尝试用Nodejllàsocket.io构建我自己的服务器,用于服务器 - 客户端通信.它非常简单:从一个接收数据并将其广播到其他人.它似乎工作正常,直到物理部分进入:服务器必须信任客户端,当他们说有什么东西被击中或爆炸,然后广播到其他客户端.更不用说受骗的客户端,由于网络延迟,客户端的物理模拟会有所不同.例如,一个坦克可能会被撞到这个客户端,但它应该被覆盖在另一个的墙后面并保持活着,但是由于潜伏期,他身后的坦克会抓住子弹并爆炸.在这些情况下,服务器不知道要收听哪一个.

更新

  • 正如下面提到的@Catwood,Photon PUN对我来说是另一种选择.之前我曾经按照他们的一个教程.Photon不需要播放器就像Unity网络一样是"服务器".但是如何在服务器上实现我的游戏逻辑呢?(用于权威服务器目的)
  • 显然,Smartfoxserver是另一个好的(和昂贵的)选项.我没有深入了解他们的API文档.我不知道我是否可以实现我的游戏逻辑和规则(为简单起见,他们的教程跳过这一部分).

总之,我需要一个关于我的游戏服务器的建议:

  • 是权威服务器
  • 可以处理游戏规则并决定会发生什么(也许应该有自己的物理引擎)
  • 适用于Unity2D
  • Javascript,C#,Java是首选!

我是否正确的方向,因为看起来像一些游戏服务器服务(如Photon,Unity网络)只是不关心如何在服务器上实现游戏逻辑.它是否使它们不是权威服务器?

我对这个领域很新,任何事都会受到赞赏!

Gar*_*son 12

我建议像为NodeJS一样为您的游戏创建自己的服务器.我所知道的大部分解决方案都很难使用,无法做到你想要的东西.

例如,暴雪游戏的Hearthstone基于Unity为客户端而且有一个定制的服务器端.

以下是有关如何创建游戏服务器的一些建议.

它似乎工作正常,直到物理部分进入:服务器必须信任客户端,当他们说有什么东西被击中或爆炸,然后广播到其他客户端.

在创建服务器时,您必须在服务器端而不是客户端做出每个重要的决策.启动聚会的是服务器,因此服务器必须具有以下信息

  • 地图的大小
  • 玩家数量
  • 每个玩家的数据(健康点,位置,大小,攻击速度......)
  • 做出决定所需的任何其他信息

现在,客户端应始终向服务器发送非常小的信号,如下所示

  • 向左移动
  • 加入派对
  • 射击
  • 右旋
  • 等等...

根据用户的操作和用户数据,服务器可以运行游戏的"模拟".

  • 检查是否允许该操作
  • 如果允许,请模拟操作.如果不是,请将其放入队列中
  • 向用户发送有关正在发生的事情的信息(玩家一击,玩家二死,玩家四移左等等)

有了这个,服务器知道什么时候发生了什么并决定发生了什么.您不依赖客户端信息,只接收玩家所需的操作.

但是,正如您所说,由于延迟和其他网络因素,您的客户端不能过于依赖服务器.在现代游戏中,客户端拥有与服务器相同的关于播放器的数据,并不总是依赖服务器在屏幕上显示正在发生的事情.

如果您玩过一些在线游戏,您可能已经注意到当与服务器的连接丢失时,您可以继续玩(移动,拍摄等等)的时间很短,但除了您之外什么也没有动.这是因为即使没有服务器信息,客户端也会根据您的操作继续"运行"游戏.

但是,为了避免客户端向播放器显示的内容与服务器模拟中发生的事情之间存在巨大差异,客户端和服务器会定期"同步".

例如,如果您决定向左移动,则客户端会知道您的移动速度,以便它可以显示移动而不依赖于服务器.

当同步发生时,服务器向客户端发送关键信息,客户端使用服务器发送的内容更改当前显示的任何信息.

在左移动示例中,如果您在服务器和客户端上的移动速度不同,当客户端收到同步订单时,您会注意到您的播放器将从显示的位置"远程移植"到另一个位置.如果某些数据包丢失或由于高延迟,也会发生这种情况.

在服务器端和客户端创建在线游戏时,处理lanncy是一个巨大的挑战,而这不是这个问题的主题.

总而言之,您的服务器应该

  • 是自制的
  • 仅接收来自客户的操作
  • 模拟游戏
  • 向客户发送有关正在发生的事情的信息
  • 定期与客户端同步

希望这个帮助=)


以下是有关如何在服务器中添加逻辑的一些说明.之前的小免责声明,我从未使用过NodeJS,因此我不知道这是否可以使用NodeJS实现,我通常使用C++.

现在为你的游戏,我假设玩家只能使用动作MOVE.

当用户连接到您的服务器时,您可以启动游戏.因为您的用户可以移动,这意味着存在2D地图,您的用户具有大小,初始位置和速度.所以你的服务器应该启动一个新的"GameParty"并初始化上面的数据.对于该示例,我们假设设置了以下默认值.

map_width = 512;
map_height = 512;
user_width = 2;
user_height = 2;
user_speed = 1;
user_posx = 20;  
user_posy = 20;
Run Code Online (Sandbox Code Playgroud)

当客户想要移动时,他会向服务器发送一个包,说他想要移动.您可以使用任何您想要的协议进行客户端< - >服务器通信,我使用二进制协议,但让我们说你使用Json

{action: move; value: left};
Run Code Online (Sandbox Code Playgroud)

这样,您的服务器就会知道用户想要向左移动.所以,你只需减少user_posxuser_speed,服务器端,你的新位置.如果此位置位于地图的边缘,则有两种选择,使用户出现在地图的另一边禁止操作.

在定期的时间间隔内,您的服务器会向玩家发送玩家的当前位置.