多人游戏 - 发送玩家位置

Multiplayer game - Send player positions

我正在创建一个简单的多人游戏(服务器权威),我需要能够向所有玩家发送所有玩家的位置

因此,每当其中一名玩家移动时,我都会这样做

private void SendPositions()
    {
        foreach (var item in ActiveUser.activeUsers)
        {
            foreach (var i in ActiveUser.activeUsers)
            {
                Net_OnMovement om = new Net_OnMovement();
                ActiveUser user = i.Value;
                om.username = user.username;
                Debug.Log(om.username);
                om.x = user.position[0];
                om.y = user.position[1];
                SendClient(item.Value.channelId, item.Value.connId, om);
            }
        }
    }

首先我更新玩家的位置,然后将所有位置发送给所有玩家(这里你只能看到发送所有到所有部分) 在客户端,当用户名等于客户端的用户名时,我移动用户,否则我移动 "otherPlayer(s)" 当只有一个播放器时工作完美,但在连接另一个播放器后,一切都会延迟很多并且没有响应。这种发送数据的方式有问题吗?或者我应该在别处寻找错误

编辑

*玩家实际上在按下按钮后立即开始移动,但是移动很慢并且在释放按钮后它会继续移动很长时间(我按住的时间越长它继续移动的时间越长) - 这实际上意味着服务器不能'我猜是不是跟不上节奏?

这取决于您的测试环境,但如果它不在本地网络上,那么您遇到的只是简单的网络延迟。通信不是即时的,可能需要或多或少的时间,具体取决于您与服务器的连接和距离。

发生的事情是,作为玩家,您正在将移动命令传输到服务器,您必须等待服务器回复更新的位置才能真正看到自己移动。如果服务器有 50 毫秒的延迟(这是一个正常的值),那么您将不得不等待 100 毫秒才能看到正在更新的位置(60 帧每秒 6 帧),从而导致滞后感。

这是一个众所周知的问题,有多种解决方案。快节奏游戏中最常见的一种称为客户端预测和服务器协调。基本上,当您收到输入时,您让玩家立即移动到客户端,这样就没有滞后的感觉(这是客户端预测)。但是由于您的服务器仍然拥有权限并且您在服务器上处于领先地位,因此您的玩家将被放回服务器认为您所在的位置,这将在客户端造成不稳定的动作。为防止这种情况,您必须在收到服务器更新时检查玩家给出的玩家位置是否是客户端预测的,如果是,则不要强制玩家返回该位置(即服务器协调)。

我强烈建议您阅读 this guide 以更好地理解客户端-服务器架构的网络问题。