说说我的理解吧,感觉下面的很多答主都没说到点子上。

先解释渲染与逻辑分离,这个方案早在上世界90年代的游戏《帝国时代》里面就有用到。当时看完论文我就有很多疑惑,由于渲染要根据逻辑数据执行,那么就算把二者拆离,只要逻辑帧不运行,渲染再多跑多少帧那下一个逻辑帧来之前不还是显示静止的画面么?比如下图第二个例子,高延迟下(1000ms)执行一个逻辑帧以及19个渲染帧,假如逻辑帧执行完算出A对象的位置为(0,0,1),那么后面19帧渲染不还是拿(0,0,1)的位置进行渲染么?

后来我思考得到结论,其实这个例子中的1000ms都属于一个逻辑帧,而不只是最前面的那一帧,但是涉及到游戏核心逻辑的计算确实只在第一帧执行。渲染与逻辑分离并不是说逻辑执行完各个端的Input逻辑后就完全不执行任何逻辑了。而是在当前逻辑帧先处理完玩家行为逻辑后,游戏还可以在所谓的“渲染帧”里面执行插值的“逻辑”来平滑对象的位置,但是后续的渲染帧里面并不会执行任何和玩家行为有关的逻辑。也就是渲染帧不会有影响到游戏玩法逻辑的计算,也不会去修改物理碰撞位置。在虚幻引擎里面(采用状态同步,不过思路一致),对象的平滑是通过胶囊体和Mesh模型计算分离而实现的,也就是说一个对象在收到服务器数据并等待下次数据前会去用Mesh模型去进行插值(类比渲染帧),而胶囊体的位置在刚收到数据后设置过一次后就不再变化过(类似逻辑帧)。

回到题主的问题:

1.我个人觉得王者荣耀这样的moba游戏一般不需要那么高精度的碰撞检测,也就是没有必要严格按照动画渲染的位置进行碰撞检测。在稳定帧率以及网络比较稳定的情况下不会向我上面图画那样逻辑位置与渲染位置差距那么大(把蓝色方块想象成一个武器),所以你把武器碰撞挂在动画骨骼上用逻辑帧去检测就可以了(渲染帧不会修改物理碰撞盒的位置)。如果想让动画与碰撞保持一致,可能需要提高逻辑帧的计算频率,像其他答主说的那样事先设置好武器的位置变化曲线我认为并不能做到完全一致。

2.为什么有“我”的概念?你如果做过网络游戏就会明白,本地玩家/本地其他玩家的同步策略一般是不同的。因为你在执行操作的时候可以立刻在本地响应并发送给服务器,如果服务器认为你的操作合法你就可以继续执行,而其他的玩家行为是通过服务器转发同步过来的,所以必定有延迟(其他客户端->服务器->本地客户端)。根据这种情况,我们会制定各种策略来优化玩家的体验(本地玩家行为立刻响应就是一种,我们一般叫预测回滚)。在虚幻引擎中,我们常常会看到这样的代码

if(GetLocalRole() == ROLE_AUTONOMOUS) //如果角色是本地玩家控制

if(GetLocalRole() == ROLE_SIMULATS)//如果角色是其他玩家控制

但是在帧同步中,我们不希望有这种区分,因为无论是本地玩家还是其他的玩家都是“收到Input->执行对应的逻辑”。所以,我们不应该假设当前的对象属于哪种玩家, 也不应该出现类似上面的判断代码并进入不同的分支。

最后一个问题,由于没有实际做MOBA的项目经验,这里就不多说了。