技术复盘:用指令帧同步做 Unity RTS 网游/手游

这篇具有很好参考价值的文章主要介绍了技术复盘:用指令帧同步做 Unity RTS 网游/手游。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        这个项目目前由于各种原因已经结束了,最终没能做到上架那一步,不过RTS的所有坑都踩了一遍。本人是RTS游戏爱好者,这篇文章先泛泛谈一下关键技术问题的遇到的大坑。后面有空再补上细节和代码。

一、最重要的问题是网络同步,没有之一

        对于RTS,最重要的就是网络同步问题,无法回避,影响全局,甚至决定成败。

0)网游?局域网游戏?

        这个问题必须首先回答,如果你选择了网游,首先扪心自问:有没有足够的启动资金。

        如果没有足够的启动资金,而又决定做网游RTS,那么这条道路是极其艰辛的,具体看下面。

1)状态同步/帧同步/指令帧同步/网络状态指令帧同步的选择

        同步方式:本地玩家的数据和对战玩家的数据以怎样的形式进行同步。

        ①状态同步:每隔一段时间,如100ms,将所有玩家的所有单位的所有数据(坦克、兵、飞机的坐标、血量、状态和其他一些参数)同步(设置为同一个数据)。

        那么这个大家都认同的数据从哪里来?如果是局域网游戏,并且不care反作弊,那么选择其中一个玩家作为主机,其余玩家每次同步从主机这里取数据完成同步就OK.

        具体实现:说起来挺复杂,但是在Unity 上有个叫做Mirror(镜像)的插件,只要在主机端添加添加几个组件,设置为主机,并且给每个需要同步的兵/建筑/子弹挂载好相应脚本,所有位置/属性则会自动同步,基本上不用关心网络。这种方式下,Gameplay方面基本上跟开发单机的模式是一样的,这里不过多赘述。

       ②帧同步:这是一个很空泛的概念。主要有介绍两种它的具体子类。

       ③指令帧同步:主要区分于状态同步。

        1.网络带宽的消耗:状态同步每隔一段时间就必须将所有玩家的所有单位的状态同步一次。如果是局域网游戏还OK,毕竟局域网流量是免费的,但如果是网游:假设人口上限为100,1v1后期就会有150+个单位状态需要实时同步,3v3就会有500+单位需要实时同步,假设每秒同步5次,这个流量消耗买过服务器的都知道有多贵。

        2.反作弊与网络中心问题:做网游,基本不会选取一个玩家做为主机,通常的做法是在服务器端也运行同样的游戏,所有玩家同步数据的时候从服务器端取出数据。Unity Mirror可以实现这样的操作,即每次开一把游戏,都在服务器开一个无头模式的Unity程序并设为主机。或者自行用任意语言实现一个逻辑上和客户端一致的游戏。无论如何,服务器是要跑一遍完整逻辑的,这种情况我没有测试,但是RTS动则几百个单位,开一局,服务器运算压力都是爆炸的,要支持几百人/几千人同时上线对战。如果资金不足搞不起高性能服务器,基本不用想了。

        3.便宜的指令帧同步:只同步所有玩家的操作指令,而不同步玩家操作的单位的属性,指令,通过服务器转发给所有玩家,所有玩家的客户端运行同样的指令,得到同样的结果,这样也就用另一种方式达成了同步,但是节省了大笔流量。

例1:{id:0;cmd:build;target:[100,200]},指令表示:在100,200的坐标上,建造0号类型的单位,如电厂/矿场

例2:{id:0;cmd:move;target:[100,200]},指令表示:所有玩家的id为0的单位,移动到坐标为100,200的网格上。

例3:{id:[0,1,2,3,10];cmd:attack;target:88},指令表示:id为0,1,2,3,10号的单位,攻击id为88的单位。

        听着很美好是吧,然而指令帧同步要求的三个点

        完全一致的本地计算、完全一致的运行时序、完全一致的同步时机

        只同步指令,而不同不状态,意味着所有玩家客户端收到相同的指令后,必须计算得到完全相同的结果(比如每一帧移动的量等),而由于Unity物理引擎采用浮点运算,每台手机的浮点运算都可能得到不同的结果(大概率不同),如果每台手机接受同样的指令,而不产生同样的结果,那游戏完全是平行世界。因此列举的下述Unity API 绝对不能使用,使用指令帧同步,基本上就是告别了Unity怀抱

       ①Unity 碰撞体组件

        wtf?游戏还能没有碰撞体?避障怎么办?子弹伤害怎么办?很遗憾如果选择了指令帧同步,这些统统没有了。

        解决方法:1.引入定点数物理引擎(B站有)据说性能不太行。2.不用碰撞(我采用的方式):网格化地图,根据子弹的运动和单位所在的网格计算伤害,这是一个大坑,后面再讲。

        ②Unity Navigation寻路系统

        不能用原因1:Navigation本身基于是浮点+物理碰撞,无法同步。

        不能用原因2:Navigation动态避障本身有缺陷,这点在Unity论坛上可以找到很多帖子,运行过程中动态添加障碍物会产生瞬移,或者失效。而对于RTS这种频繁有单位走走停停,有新建筑产生/销毁的游戏,除非深入底层修改源码不然无解

        解决方法:自行编写寻路算法,这也是一个大坑后面再讲。

        ③Unity 刚体组件

         所有和物理有关的力全部无法使用,原因也是因为浮点运算得不到一致结果。

        ④Update方法、IEnumorator、Coroutine

        Update方法:只能用于渲染帧更新,而不能在逻辑计算中使用,而必须自己另开一个线程,在这个线程中调用单位的更新逻辑。原因是逻辑和渲染帧必须分离。如果不分离,游戏的FPS就会强行和网络同步绑定。具体来说是比如服务器每100毫秒同步一次指令,那么逻辑帧数就是10帧每秒,如果你在Update中更新逻辑,就会导致游戏的实际帧数也必须阻塞到10帧每秒,如果你需要游戏以60FPS运行,那么你服务器就得每秒同步60次,这基本不可能(每次收发数据的基础延时都有50ms),另外还有不同客户端渲染帧数不一致的问题。所有渲染/逻辑帧分离,是帧同步的绝对要做的。

        IEnumorator、Coroutine:按照Unity官方的资料,这两个对指令帧同步应该是没有影响的,但是据我观察协程的启停并不是确定时许的,不信邪可以试试,我建议不要去用

        以上是第一部分网络的相关大坑。后面的有时间再更

        文章来源地址https://www.toymoban.com/news/detail-808427.html

到了这里,关于技术复盘:用指令帧同步做 Unity RTS 网游/手游的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

    今天想给大家分享的主题是如何实现RTS类型游戏中的游戏单位角色控制 本文中会介绍如何运用最新的ECS架构来实现游戏单位控制 上方代码实现的功能是获取被鼠标框选的游戏单位,如果需要源代码可以在文末添加爱丽丝老师的QQ或者微信号领取 代码讲解 获取鼠标框选方框的

    2023年04月12日
    浏览(51)
  • 【游戏开发实战】Unity手游第一人称视角,双摇杆控制,FPS射击游戏Demo(教程 | 含Demo工程源码)

    一、前言 嗨,大家好,我是新发。 有同学私信我,问我能不能写一篇Unity手游第一人称视角控制的教程, 那么,今天就来做个 Demo 吧~ 注: Demo 工程源码见文章末尾 最终效果如下: 二、实现方案 1、无主之地,第一人称视角 第一人称视角的游戏大家应该不陌生,比如《无主

    2023年04月08日
    浏览(53)
  • 【Unity】【VR开发】Unity云同步功能使用心得

    有时出差,旅行等等也带着电脑,晚上想要继续编辑项目,就需要用到云同步功能。目前实践下来,发现有些内容可以同步,有些内容则是不可以同步的,总结如下。 UnityHub的项目面板中有两个选项卡:项目和云端项目。 鼠标挪动到想要云同步的本地项目上,项目名右上角会

    2024年02月21日
    浏览(54)
  • Unity中Shader指令优化(编译后指令解析)

    我们先读懂Shader编译后代码,才能对Shader进行合理的优化 我们目前先只编译到 D3D 平台 这是编译后的代码(我们来逐步分析):

    2024年02月04日
    浏览(43)
  • Unity中Shader指令优化

    上一篇文章中,我们解析了Shader解析后的代码。我们在这篇文章中来看怎么实现Shader指令优化 Unity中Shader指令优化(编译后指令解析) 在DirectX平台,常数运算是不占指令数的。但是,稳妥起见我们最好自己计算好常数计算的结果。防止其他平台认为常数运算需要占指令。

    2024年02月03日
    浏览(39)
  • 【Unity】 HTFramework框架(四十五)【进阶篇】指令系统-自定义指令

    更新日期:2023年6月19日。 Github源码:[点我获取源码] Gitee源码:[点我获取源码] 指令系统详解:【Unity】 HTFramework框架(四十四)【进阶篇】指令系统。 使用 HTFramework 的 指令系统 ,可以将一段指令代码即时编译并执行。 例如,我需要这样一个功能: 新建一个游戏物体,将

    2024年02月11日
    浏览(77)
  • Unity运用socket传输信息(同步)

    客户端: 在UGUI中创建两个Button,一个是连接服务器,一个是发送消息的按钮,分别绑定Connection和SendMessage两个函数 并且创建一个InputField和一个Text文本,Text文本用于显示服务器回传的消息,InputField用于输入要发送的消息 以下是代码: 客户端代码 服务端: 服务端采用VS提供

    2024年02月08日
    浏览(37)
  • 【unity】【WebRTC】从0开始创建一个Unity远程媒体流app-构建可同步场景

    最近在研究远程画面,所以就实践了一下。技术采用我认为比较合适的WebRTC。 这篇文章的基础是我的另一篇博文,如果希望顺利完成本篇操作,请先关注我后查询我的如下博文: 【WebRTC】【Unity】Unity Web RTC1-Unity中简单实现远程画面 上一篇地址: 【WebRTC】【Unity】Unity Web R

    2024年04月27日
    浏览(33)
  • Unity垂直同步:帧率和刷新率

             帧率(英语:frame rate)是用于测量显示帧数的度量。测量单位为“每秒显示帧数”(frame per second,FPS)或“赫兹”,一般来说FPS用于描述视频、电子绘图或游戏每秒播放多少帧。         显示器的刷新率是指显示器每秒绘制新图像的次数。其单位为赫兹 (

    2024年02月08日
    浏览(49)
  • 【Unity】 HTFramework框架(四十四)【进阶篇】指令系统

    更新日期:2023年5月29日。 Github源码:[点我获取源码] Gitee源码:[点我获取源码] 指令系统 为Unity动态修补程序、热更新等提供了另一种补充方案,我们可以将任意一段 指令代码 即时编译并执行(请放心,即时编译的性能开销极低),达到运行时随意修改程序功能的骚操作。

    2024年02月09日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包