如何计算吃鸡游戏的物理碰撞?

如何计算吃鸡游戏的物理碰撞?

本期我们聚集了这几个话题:如何计算吃鸡游戏的物理碰撞、坐标比较大的时候模型抖动闪烁、修改BackBuffer默认尺寸、PostProcessing 的Bloom的性能消耗...


这是第126篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ群:793972859(原群已满员)


服务器同步

Q1:由于吃鸡类游戏需要强同步,很多时候可能使用帧同步,客户端无法直接使用物理引擎,或者状态同步情况下服务器需要计算碰撞等。此时怎么处理这部分的碰撞呢?数据结构又是怎样呢?

A1:如果让我选择技术方案的话,类似绝地求生这种3D自由视角的吃鸡游戏我绝对不会选择帧同步,原因有:
1)射击游戏在玩家移动、开枪等操作上会有较强的手感体验上的诉求,帧同步很难支持即时的操作反馈;
2)自由视角的吃鸡虽然没有战争迷雾,但是会有视距的问题,使用帧同步把所有信息广播给玩家,外挂做起来简单太容易,而吃鸡手游中标定其他玩家位置这样的外挂又有很大的优势,所以本质上不适合。
不知道题主说的帧同步和我理解的帧同步是否一致。然后,基于状态同步,服务器可以跑物理,但是真实的物理完全在服务器跑,对于服务器的压力太大,需要付出的成本过高,一台物理机也可能承载不了多少同时在线的玩家消耗,你要评估下运维的成本是否可以接受。常见的做法:

1)简化3D物理,根据上下文状态只做部分关键判定,比如类似命中这样的。不过因为物理中的数据计算比较敏感,浮点误差都可能导致结果不一致,这里的工作量和坑应该都不少。

2)使用2D物理系统代替3D物理系统来做,在物理计算中去掉高度,只做2D的碰撞,结合专门的检测进程,是一种可行的检测方案,性价比比较高;

3)客户端判定,服务器验证,先相信客户端的判定,然后进行客户端表现,然后服务器基于数据做验证,这里可能会使用2D物理引擎,也可能在核心判定中再添加一些比如高度的信息等来做;

4)客户端判定,加严格的反外挂方式,封号之类的。这种当然你也要可以判断出来玩家作弊,判断方式可以未必实时去做,类似帧同步放后面通过回放模拟来做也可以,这时候有可能可以使用3D物理的来做(经验上依然不推荐,只是从实时变成离线,对于性能的要求没有那么高了,3D成为一个可能性)。

5)先不做,等游戏火了有钱了再加,没火的话,也没什么专业的外挂团队来使坏。
至于数据结构,太细节了,根据需求自己设计吧。2D的直接集成开源的2D引擎就可以了。
感谢贾伟昊@UWA问答社区提供了回答

A2:同意贾公的观点。顺带补充几点:
1)这游戏除了角色,还有非常多的第三方信息需要同步,包括:门、载具和物资等。如果是帧同步,那还得同步弹药量和消耗品等等...即使是端游,也是信息量巨大。所以用状态同步比较现实。
2)不是特别熟悉虚幻引擎,而虚幻引擎用了NVIDIA的Physx,市面上的吃鸡手游应该都是以此为基础做的,那么服务器如何实时或离线运算Physx应该也是有参考的。联想到之前有篇关于守望先锋中同步平滑的文章,题主可以去参考下。
3)其实物理碰撞不是啥大问题,外挂中自瞄和透视才是大问题。早期的PUBG连人物移速都不验证的,为了物理碰撞而采用帧同步,可能其他方面踩的坑要更多。
感谢史云柯@UWA问答社区提供了回答

A3:感觉楼上已经解答的很好了,补充一个反外挂的办法吧:可以把本来需要在服务器进行的复杂运算,先让涉及到的客户端发一个结果,再将结果和运算及参数发到若干客户端来执行,再做投票验证,这样可以降低一些服务器的负载。
感谢郭瑞@UWA问答社区提供了回答

A4:我再补充一篇来自ValveSoftware的技术文档《Source Multiplayer Networking》:
https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
这篇也是基于状态同步架构的。里面提到的延迟补偿和客户端输入预测技术,是目前比较主流的、用来对抗延迟带来的糟糕体验的方法。
感谢张锐@UWA问答社区提供了回答

A5:吃鸡玩家数量一般在100个以上,这种情况下用帧同步需要同步的数据量会很大,延迟也会比较严重。因为帧同步一般需要收集所有同场景玩家的输入,然后分发给各个客户端,让各个客户端用相同的逻辑自己去计算每个玩家的位置、状态,游戏逻辑是跑在客户端的。MOBA适合使用帧同步是因为一场比赛只有10个玩家。
我觉得吃鸡还是适合状态同步。状态同步怕的是角色太多,导致需要同步状态的角色过多,造成网络同步数据量大。吃鸡没有什么野怪,全部是玩家,所以场景里角色就是玩家。可拾取的装备需要同步的数据比较少,基本上需要一个位置坐标就行了,玩家身上的状态数据量要多很多。客户端看不见的玩家、装备,完全可以不用同步,因为逻辑完全跑在服务器端,客户端只需按照服务器的逻辑做绘制就行了。
关于游戏手感的问题,FPS游戏对延迟的要求是所有游戏类型中最高的。如果玩家网络不是很好,也很难优化到比较好的情况。客户端先行可以先做显示的预判例如:击中后的血迹。但是数值结果还是依靠服务器端的计算,否则很容易被外挂利用。即使服务器结果判定没有打中,问题也不是很大,最多就是玩家看到有几枪打中有血迹特效,但是对方没扣血。这种情况大概率出现在网络环境不好的情况。
感谢ZFK@UWA问答社区提供了回答

该问答来自问答社区,欢迎大家转至社区进一步交流:
https://answer.uwa4d.com/question/5a90c4960b827e2c0bfdcfc4


计算精度

Q2:我的项目在坐标比较大(20000,0,20000)的时候有如下2个问题:
1)模型移动会发现轻微抖动;
2)安卓上镜头转动时发现模型闪烁,只有安卓这样,iOS和PC正常。Unity版本2017.4.2,测试工程已经上传至UWA问答社区。

A1:
2637(0).png
http://www.songho.ca/opengl/gl_projectionmatrix.html
在NDC空间中,离近切面近的点,Z的精度会比较高,离远切面近的点,Z的精度会很低。如果远切面的值过大,那么就会容易出现Z-Fighting。基于透视原理,基本上这个问题是无解的。只能考虑曲线救国的方法绕过这个问题。
感谢凯奥斯@UWA问答社区提供了回答

A2:补充个现成参考方案:World Streamer
这个是个超大世界Streaming的完整解决方案,里头也实现了一个Floating Point Fix功能,就是解决坐标过大导致精度不足的问题。具体的做法大家也提到了,就是把世界的坐标拉回来,另外NavMesh这块会有坑,最新版的World Streamer已经支持Unity 5.6+的NavMesh移动。实现代码可参考里头的WorldMover.cs。用法可以参考他们文档Floating Point Fix System的说明。
感谢招文勇@UWA问答社区提供了回答

该回答由UWA提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5afb8a326b104d27ac3aad62


渲染

Q3:我们项目在做优化,之前是在游戏内将场景渲染在一张较小的RenderTexture上最后翻回BackBuffer,但是这样还是会多出来一次RenderTexture的拷贝。从我以往的经验来看,可以直接修改BackBuffer的默认尺寸,这样就可以避免一次RenderTexture的拷贝同时也减小RenderTexture的尺寸,不知道Unity在Android上是否可以直接修改BackBuffer的尺寸。我们使用的是Unity 5.5.4,希望大神解答一下。其实这个就类似与高版本Unity的DPI设置,但是我们现在无法更新Unity版本。

有个思路是硬改安卓层Surface的大小,是否可行还有兼容性问题需要验证。
另外隐约记得降低分辨率的时候Unity有个输出,不支持硬件缩放的情况下才会走Blit的方式,Logcat里的输出是这个:
Hardware resolution scaling not supported, falling back to software scaling (blit).
相关资料(后半部分):
https://forum.unity.com/threads/standard-shader-for-mobile.368672
建议直接调低分辨率,安卓上Unity会有个尝试硬件缩放的过程。
另外,Unity 5在安卓上总是会有一次全屏Blit的,并不会直接往BackBuffer里绘制。
相关参考:https://forum.unity.com/threads/big-performance-issue-with-unity5-on-android.338847

感谢littlesome@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5b7fc7b01e88b37d34e65361


渲染

Q4:我想了解下,PostProcessing 的Bloom,只开一个Layer和开所有Layer的消耗是一样的吗?因为是屏幕后特效,它只取渲染完成后的图片做一次处理,所以想确认下自己的测试是否正确。

官方Github上的文档是这么说的:
请输入图片描述
这个Layer跟Unity其他地方的Layer作用类似,是用来做Filter的,所以渲染的效率是不影响,但是对于不需要Bloom的相机还是可以设置一下把它屏蔽掉,这样可以更高效。

该回答由UWA提供,欢迎大家转至社区进一步交流:
https://answer.uwa4d.com/question/5b7b702c339d267d357c6e00

今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(原群已满员)