![1b870743c8afba9d3a591e16d4aaae63.png](https://i-blog.csdnimg.cn/blog_migrate/c84fa285a09eb1d449b07796f0cca9de.jpeg)
之前在玩手游《跑跑卡丁车》的时候,发现其录像细节做得很好,支持拖拽进度,还原玩家操作,我个人感觉就差一个功能:timescale缩放。玩家去看录像,一般就是去学习某个操作技巧,然而大多数游戏不支持操作还原,这就让录像存在的意义大打折扣。同时一个录像中肯定有一些是关键操作,玩家对其感兴趣,所以需要反复观看研究,这就涉及到了一个录像进度拖拽的设计。再说timescale,玩家可以做到播放速度变慢,更易观察操作细节。
![02f68b35658cd21199c5ca25dd3bb707.png](https://i-blog.csdnimg.cn/blog_migrate/e8ec9bc4ce254266655c653ffaf516fb.png)
这里给录像设立一些前提条件:
- 支持拖拽录像进度
- 可以还原玩家具体操作
- 可以进行timescale的缩放
- Pvp录像,而不仅是单机录像
我们来思考一下,如何设计这种录像。
- 拖拽进度,其实就是改变当前播放游标在时间轴上的位置
- 还原玩家操作,那就需要记录玩家在时间轴上某游标时刻的一些按键/触屏操作
- timesclae缩放,可以理解为将时间轴横向进行了拉伸或者压缩
- pvp录像,也就是不仅需要记录自己的操作与一些必要的状态数据,还需要记录其他网络玩家的操作以及必要状态数据
![98e8e6970e0ea24bedaad62234d6e303.png](https://i-blog.csdnimg.cn/blog_migrate/0a864aeab5e069c0a3fc3478cc8287cc.png)
同步方式分为帧同步系列,状态同步系列。帧同步都在client执行,server只转发,实现较简单(下面设计方式中会涉及到),所以这里不讨论帧同步录像。
分析至此,有3种想法出现:
(1):将录像作为一个真实的“战斗”去设计
一般战斗 是下图的流程。这里以最简单的client/server交互方式去说明,至于客户端预测先行,回滚等先不考虑。
![17627942dc90130484a471b067fa9f78.png](https://i-blog.csdnimg.cn/blog_migrate/61479ab369b0b6bc42fdba5dbc307c8d.png)
客户端发出请求,给服务器,服务器响应,然后计算即时状态反馈给客户端。
而上述真实战斗流程与录像几乎没有什么差别,只是输入操作一个是实时按键的,一个是被记录下来的"虚拟"按键。那么我们只需要得到录像初始时刻,各个玩家的原始状态数据,以及时间轴上的各个玩家的操作数据(比如按了加速按钮,按了漂移按钮等),然后使用这些数据原封不动的输入战斗系统,就可以开始一场实时录像。这对于战斗系统的设计要求比较高,如果程序设计战斗系统的时候,没有考虑到为录像预留设计,那么可能重构比较麻烦。
但是这种方式,也存在一些细节问题,
必须记录各个玩家的初始状态数据
必须记录当时战斗的时候使用的一些表格数据
弱网络环境下会露馅
如果不记录,那么后期改表数据,玩家等级变化等情况就会导致录像表现与原始战斗表现不一致,甚至战斗结果出现不一致。因为 战斗过程中肯定会使用到技能表,buff表等表格。举个例子,原来战斗的时候,你是3级,然后触屏技能按钮,释放技能id为x的技能,这个x技能会受到当前等级的限制从而做出一些不一样的逻辑/表现。然而现在你等级已经到10级了,再去以这种方式去查看原来那场战斗,必然x技能会受到影响。何况,如果某个版本策划将x技能的某个参数进行了修改,比如技能作用半径,比如氮气加速度,那就更加导致结果的不一致。
经常会在某些游戏录像中看到提示:当前版本不支持查看上一个版本的录像,我猜其实就是因为相关表格进行了改动。
修改timescale,客户端比较容易实现,但是server就不好去实现了,需要server也构建一套类似可缩放的时间轴机制。可以简单理解为:不支持修改timescale。
很遗憾,这种方式不支持进度拖拽。
(2):不以真实战斗的形式去设计
这种方式相比较第一种方式,少了与server的交互,会导致很多OnReceivedXXX失效,那么我们直接去模拟,让这些本该失效的OnReveivedXXX生效即可,这样可以让代码整体改动较小。这种方式可以理解为自己在client端构造了一个虚拟server(其实就是Req中直接调用OnReceivedXXX)。
![7a84da5bee2a362848ee8decb4339972.png](https://i-blog.csdnimg.cn/blog_migrate/4f73399e40ea75931d654193515a1924.png)
该实现方式也需要记录初始状态数据(不仅自己,还包括其他pvp玩家), 也会受到表格改动的影响,原因同第一种方式。不受到网络环境的影响,毕竟不需要联网即可完成。
想进行timescale修改,直接修改Unity的Time.timescale即可(一般情况下够用,注意update依然在执行),当然最好是有一套完善的战斗状态机机制,可以只让某一部分进行timescale的缩放,而不是全局缩放,比如《保卫萝卜》,暂停战斗的时候,我们其实依然可以去布局保卫者(注意时间戳忽略暂停影响)。
支持拖拽进度,其实是客户端基于一些关键时间点的状态数据进行插值。
那么这些相关状态数据,操作数据是谁去保存呢?正常来说,server和client的数据数据应该是同步一致的,那么双方谁去记录数据都可以,但是最好是client去记录,因为不一定每一个战斗都需要去记录,这部分选择权在玩家这边,让玩家去上传其觉得不错的战斗数据从而形成战斗录像数据。如果让server去记录,数据量较大。
数据内容大体上应该是:操作时间戳(或者桢),操作的时候某些关键状态数据, 不受操作控制的一些关键状态数据,比如车辆碰撞数据。。。
(3)就是录个视频
正常手游应该不会这么做
如果你想知道某个游戏的录像是通过第一种方式实现的,还是第二种方式实现的?
录像开始后 关掉手机网络去看一下,是否还能继续播下去。
上述只是本人的一些思考与想法,不保证可行。