admin 2025-12-09 01:29:12 跨端同步

【DIY游戏开发记录】多人联机游戏的一种移动同步方法

一、前言

在开发多人联机游戏过程中遇到的移动同步问题,不断尝试然后改进,进而得到的目前可以接受的同步效果。这种办法可以用于少数人联机,并不适合大型多人同时在线(例如MMORPG千人、万人同屏的国战后续也会尝试这种类型同步,处理好AIO)。本文是个人尝试的一种方法,不一定最优,如有纰漏或者建议,欢迎指正,不胜感谢。[引用请注明出处]

二、一次失败的尝试

第一次尝试是参考了简单的帧同步方式,为了简化流程,只画出A,B 两个玩家连接游戏

(1)理想中的玩家交互流程如下图

①玩家A在客户端A操作角色从A移动到A"

这时候unity客户端端捕获玩家的键盘鼠标输入,转化为通用输入的命令字

② 数据包发送给服务器

按照约定的协议格式,把玩家操作命令字,打包成网络数据包Package ,发送给服务器

③ 服务器处理并转发

服务端收到消息后,找到需要转发的玩家,把消息转发一份,并更新服务器上玩家的状态

④ 客户端A和B收到消息

解析消息,玩家A想要移动的指令,在各自客户端通过unity控制角色的移动操作

(2) 实际遇到的问题

理想中这套流程是可以保证AB玩家看到的画面都是实时同步到,在本机上测试是没有问题的,然后发布到云服务器上后测试却出现了问题。 实际情况中,每个人的网络状况都是不稳定的,于是就成了下面两种情况。。

①客户端A由于网络问题,发出去的命令指令集,迟迟到不了服务端,导致服务端迟迟不会包,客户端A收不到回包角色就不会执行移动命令,玩家体感上就是按了半天没反应

①客户端B由于接受第二个停止命令的时候,网络问题波动导致客户端B收包延时,B客户端看到玩家A停在A’,实际上A早已停止在A",导致玩家B和玩家A的画面不同步问题

(3)杂谈

虽然实践失败了,但是也是一种经验,记录一下 演示视频: 还原原神躲猫猫 git仓库:代码

二、 优化版本详述

针对第一次的失败,有了以下优化

(1)优化玩家操作手感卡顿问题

玩家操作手感卡顿的原因主要是客户端要收到服务器的回包,才能真正的进行客户端表现,一旦网络出现波动第一影响的就是玩家操作手感,而且个人体验下来体验很不好。优化点如下,玩家操作后,客户端直接表现,同时给服务端发Cmd包,服务端收到后校验并广播Cmd包给其他玩家 此时自己的移动就不收网络波动影响,如图所示 这种模式下,解决了玩家体验卡顿的问题,但还没有解决同步问题。也就是T1时刻客户端A的屏幕显示,玩家A已经到了A",而玩家B的显示器要到T4时刻,玩家A才会运动A",这就引入了下一个优化方案

(2)优化位置不同步问题

由于运动是连续的,而且联机玩家一般不能直接看到其他人的屏幕,所以这里是有个取舍的,做到游玩体验可以接受即可。优化方案如下:每个客户端定时(每隔时间T)上报自己的状态包,服务端收到后更新玩家状态,并同步给其他玩家Sync包,其他玩家收到服务器的Sync包后,进行运动修正,以下图为例 T3时刻,客户端B收到了A玩家的移动命令,经过计算,从T4~T7时间移动到A"(此时客户端A视野中,玩家A早已移动到了A"),随后不久客户端A发送了Report命令,在T5时刻收到了服务器同步命令Sync,此时客户端B中玩家移动到了A’, 经过移动计算修正,会把原来花费时间T5-T7从A’到A"的任务,修正为T5-T6从A"移动到A",这样一来就尽快做到客户端A和客户端B的同步。 当然,这里仅仅是举例子,真实的修正并不是简单的时间缩短。

修正效果就类似下图:

由于时间和运动是连续的

只要误差在可以接受的范围内,不断移动,不断修正,就可以达到一个收敛的状态,客户端A和B做到了可以接受的同步效果。当然如果断网太久,误差过大,那就只能做JumpMove了,也没必要修正

(3) 一些说明

客户端是unity的,资源素材比较大,只上传了部分代码 服务器是基于C++协程Rpc框架Msec改造的,通讯协议protobuf-3.10 代码链接:服务端代码 代码链接:客户端代码 演示视频暂时没有, 引用请注明出处

Copyright © 2088 极光云巢-多端游戏数据互通平台 All Rights Reserved.
友情链接