【问题标题】:Building a simple online game server for Unity为 Unity 构建一个简单的在线游戏服务器
【发布时间】:2015-05-28 09:20:32
【问题描述】:

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

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

  • 然后我尝试使用 Nodejs là socket.io 构建自己的服务器以进行服务器-客户端通信。这很简单:从一个接收数据并将它们广播给其他人。在物理部分出现之前,它似乎工作正常:当客户端说有东西被击中或爆炸时,服务器必须信任客户端,然后将其广播给其他客户端。且不说被骗客户端,随着网络延迟,客户端的物理模拟会有所不同。例如,一辆坦克可能被这个客户击中,但它应该被另一个客户挡在墙后面并保持生命,但由于延迟,他身后的坦克接住了子弹并爆炸。在这些情况下,服务器不知道该听哪一个。

更新

  • 正如下面提到的@Catwood,Photon PUN 是我的另一个选择。一世 以前遵循过他们的教程之一。 Photon 不需要像 Unity 网络那样让玩家成为“服务器”。但是如何在服务器上实现我的游戏逻辑呢? (用于权威服务器)
  • 显然 Smartfoxserver 是另一个不错的(而且价格昂贵)的选择。我还没有深入了解他们的 API 文档。我不知道我是否可以实现我的游戏逻辑和规则(为了简单起见,他们的教程跳过了这部分)。

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

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

我的方向是否正确,因为似乎某些游戏服务器服务(例如 Photon、Unity 网络)并不关心如何在服务器上实现游戏逻辑。这是否使他们不再是权威服务器?

我是这个领域的新手,任何事情都会不胜感激!

【问题讨论】:

    标签: unity3d game-engine multiplayer


    【解决方案1】:

    我建议像使用 NodeJS 一样为您的游戏创建自己的服务器。我知道的大多数解决方案都很难使用,并且无法做任何你想做的事情。

    例如,暴雪游戏的《炉石传说》是基于 Unity 的客户端,并有一个定制的服务器端。

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

    在物理部分出现之前,它似乎工作正常:当客户端说有东西被击中或爆炸时,服务器必须信任客户端,然后将其广播给其他客户端。

    创建服务器时,您必须在服务器端而不是客户端做出每个重要的决策。 是服务器发起聚会,所以服务器必须有以下信息

    • 地图大小
    • 玩家人数
    • 每个玩家的数据(生命值、位置、大小、攻击速度...)
    • 做出决定所需的任何其他信息

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

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

    根据用户的动作和用户的数据,服务器可以运行“模拟”游戏。

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

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

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

    如果您玩过一些在线游戏,您可能已经注意到,当与服务器的连接断开时,您可以在很短的时间内继续玩(移动、射击等),但除了移动之外什么都不能移动你。 这是因为即使没有服务器的信息,客户端也会根据您的操作继续“运行”游戏。

    但是,为了避免客户端向玩家显示的内容与服务器模拟中发生的情况之间存在任何巨大差异,客户端和服务器会定期“同步”。

    例如,如果您决定向左移动,客户端会知道您的移动速度,因此它可以在不依赖服务器的情况下显示移动。

    当同步发生时,服务器向客户端发送关键信息,客户端将任何当前显示的信息更改为服务器发送的信息。

    在左侧移动示例中,如果您在服务器和客户端的移动速度不同,当客户端收到同步命令时,您会注意到您的玩家将从显示的位置“传送”到另一个位置。如果某些数据包丢失或由于高延迟,也会发生这种情况。

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

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

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

    希望有帮助 =)


    以下是有关如何在服务器中添加逻辑的一些说明。 之前的小免责声明,我从未使用过 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;
    

    当客户端想要移动时,他会向服务器发送一个数据包,说他想要移动。您可以使用任何您想要的协议进行客户端服务器通信,我使用二进制协议,但假设您使用 Json

    {action: move; value: left};
    

    这样,您的服务器将知道用户想要向左移动。 因此,您只需将user_posx 减少user_speed 的值即可在服务器端拥有您的新位置。如果这个位置在地图的边缘,你有两个选择,让用户出现在地图的另一边禁止操作。

    每隔一段时间,您的服务器会向客户端发送玩家的当前位置。

    【讨论】:

    • 感谢您提供的信息。我相信您在谈论客户端预测、插值和服务器协调。我已经为此工作了一两天。在您的回答中,我认为“服务器应该模拟游戏”部分现在是我的问题,因为我的服务器只是一个“哑服务器”,我不知道如何在其上实现一些模拟逻辑 =)
    • @FlySoFast 好吧,这并不难,但主要取决于您的游戏在做什么。我将编辑我的答案以添加一些精确度
    • @FlySoFast 您不一定需要服务器内部的物理引擎。因为您不需要您的服务器来运行完美的游戏模拟。 “碰撞”非常简单,因为它只是与击球方向相反的运动。现在对于“反弹”,如果您不想计算它,请不要。让客户在反弹后向您发送它的位置。您的服务器只需要检查它是否在某个反弹限制内。如果是,则服务器接受客户端的新位置。您无需对游戏的各个方面都拥有完全的权威。
    • @FlySoFast 在一个完美的世界中是的,但实际上这不是真的。每个物理引擎都试图模拟“真实物理”,但由于 CPU 过于密集,每个物理引擎都包含自己的近似值。有些比其他更好。这是一个例子media.giphy.com/media/o9awDl6tjqBvG/giphy.gif。但是,由于 2D 物理比 3D 物理更简单,因此您应该得到类似的结果。以防万一您应该包含误差范围。
    • @DavidDimalanta 这取决于您的游戏以及客户端-服务器通信的重要性。通常来说,最好让服务器 24/7 在线。但是,如果您的服务器仅用于排行榜或其他非必要功能,您可以定期停机而不影响玩家。确保您的客户在停机期间表现“正常”。抛出诸如“连接超时”之类的常规错误可能非常烦人。
    【解决方案2】:

    资产商店中有一个名为Photon 的资产,它是一个权威服务器。对于非移动设备,它也是免费的。这肯定会处理您问题的第一部分。

    这个伟大的Tutorial 会有所帮助。

    【讨论】:

    • 记住 Photon 有 20 个并发用户的限制。目前也有 ulink,但必须为此购买许可证,但与 photon 相比,它的教程很容易。然后是黑暗裂痕,它也是免费的,但与 20 个并发用户有相同的限制。 ulink : developer.muchdifferent.com/unitypark/Downloads 黑暗裂痕 : assetstore.unity3d.com/en/#!/content/16711
    • 我不知道 20 个并发用户。这是非常有限的,这是一种耻辱。
    • 确实是这样,但 ulink 没有它,您可以将其用于测试,因为它是评估副本,但在发布之前您需要获得许可。实际上我还没有找到任何真正免费的多人插件;虽然 dark rift 为 200 个并发用户提供插件 dark rift pro,价格为 50 美元 dark rift pro:assetstore.unity3d.com/en/#!/content/16712 然后他们有 650 美元的无限并发用户
    • @killer_mech “记住 Photon 有 20 个并发用户的限制” - 这取决于您获得的版本。 免费是20;他们也有 100 个; 500;和 1000 个 CCU 版本
    • @Catwood 嘿,你有使用它的经验吗?我已更新我的答案以获取更多信息。
    猜你喜欢
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 2022-12-01
    • 1970-01-01
    相关资源
    最近更新 更多