【ECS游戏架构】逻辑帧驱动带来的性能和即时性问题分析

个人拙见,如有错误敬请斧正。

根据守望先锋在GDC会议上对ECS架构的描述,所有的系统(system)都是由逻辑帧驱动的:每帧遍历所有的system,并调用system的update()更新游戏世界的状态。
在这里插入图片描述

在实际应用中这可能会存在一些问题:两帧之间资源空闲、即时性低。本文分别从 把ECS应用到帧同步、状态同步,以及对应的客户端、服务器来进行分析。

在帧同步中的具体分析

  • 客户端:负责所有核心逻辑。

    • 有资源空闲没有问题,客户端只要能流畅运行即可,没有要"榨干客户端资源"的需求。
    • 可能存在的即时性问题:负责记录每帧输入的系统s1得到本帧的输入后,要由网络发送系统s2发送给服务器。如果s2在s1之前执行,则s1记录的每帧输入要在下一帧才能由s2发送给服务器,这就产生了1帧的延迟。帧同步本来就要求低延迟,因此应该避免这种问题。
      解决方案是对系统进行排序,使系统按顺序执行,保证先记录每帧输入,然后再向服务器发送消息,这样就可以在同一帧中完成。
  • 服务器:负责转发客户端的每帧输入。

    • 资源空闲问题:服务器应该尽可能的充分利用资源以提高承载量。可以灵活调节服务器逻辑帧率,即负载高时调慢帧率,负载低时调高帧率。还可以不同系统采取不同的帧率,如处理移动的系统可以固定30帧,而战斗系统的帧率可以更高,甚至可以不由逻辑帧驱动,直接死循环执行update()

      这些方案实际上这就是对ECS进行了一些改造,但结构上还是E-C-S,只是系统的update()的驱动方式更加灵活了。

      注意,只有服务器可以这样灵活调节逻辑帧率,客户端不行。因为帧同步要保证每个客户端的每帧逻辑一致,那么让每个客户端的逻辑帧率一致,并且逻辑帧率固定,是最简单可靠的方案。如果逻辑帧率是灵活变化的,会大幅增加系统的复杂度。

    • 可能存在的即时性问题是:类似于对客户端的分析,如果网络发送系统s2在网络接收系统s1之前执行,则会产生1帧的延迟。解决方案有:对系统进行排序,或者调高网络收发系统的逻辑帧率,或者直接让网络收发系统不由逻辑帧驱动。

在状态同步中的具体分析

  • 客户端:接收服务器发来的状态进行表现。
    • 资源空闲问题:同"帧同步客户端"分析一样。
    • 即时性问题:同"帧同步客户端"分析一样。
  • 服务器:负责所有核心逻辑。状态同步服务器要做的逻辑很多,因此更有必要避免资源空闲和即时性问题。
    • 资源空闲问题:同"帧同步服务器"分析一样。
    • 即时性问题:同"帧同步服务器"分析一样。

方案总结

  • 系统按序执行,满足大部分完整逻辑尽量在一帧内完成,保证即时性。我知道要把几十个system进行排序是一件很头大的事情,但如果真的能够做到,这其实也是最简单的一种方式。

    • 将网络分为网络接收系统和网络发送系统。接收系统在所有负责逻辑的系统之前执行,而发送系统在所有负责逻辑的系统之后执行。

    • …随时想到随时补充。

  • 改变服务器system.update()的驱动方式:三种方案,灵活调节逻辑帧率、不同系统使用不同帧率、不用逻辑帧驱动。既能保证即时性,又能充分发挥性能。虽然不完全符合ECS,但无伤大雅,结构上还是E-C-S,只是系统的update()的驱动方式更加灵活了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity的ECS架构是一种基于数据的设计模式,它将游戏对象(GameObject)拆分为各个组件(Component),并且通过系统(System)来处理这些组件,以此来实现游戏逻辑的编写和管理。 在ECS架构中,数据和逻辑是分离的,每个组件只包含数据,而不包含任何逻辑。而系统则负责处理这些组件,并且根据组件的数据状态来执行相应的逻辑。 下面详细介绍Unity的ECS架构: 1. 实体(Entity) 在ECS架构中,实体(Entity)是游戏对象(GameObject)的抽象。它只是一个ID,用于标识一个游戏对象。实体没有任何的组件或者逻辑。 2. 组件(Component) 组件(Component)是游戏对象的基本元素。每个组件只包含数据,不包含任何逻辑。例如,Transform组件只包含位置、旋转和缩放等数据,而不包含任何移动或旋转的逻辑。 3. 系统(System) 系统(System)是处理组件的核心。系统会根据组件的数据状态来执行相应的逻辑。例如,移动系统会根据Transform组件的位置和速度等数据来更新游戏对象的位置。 系统可以根据需要访问一组或多组组件,并且可以通过查询语言(Query)来获取需要的组件。例如,一个移动系统可能需要访问Transform组件和Velocity组件,它可以使用查询语言来获取这些组件。 4. 状态组件(State Component) 状态组件(State Component)是一种特殊的组件,它包含游戏对象的状态信息,例如是否存活、是否受伤等。系统可以根据状态组件的数据状态来执行相应的逻辑。例如,死亡系统会根据是否存活状态组件来判断游戏对象是否死亡。 5. 事件(Event) 事件(Event)是一种可以触发系统执行逻辑的机制。例如,当游戏对象被攻击时,可以触发一个受伤事件,从而让受伤系统进行处理。 6. 工作流(Workflow) 工作流(Workflow)是一种将多个系统组合起来处理游戏逻辑的机制。例如,一个游戏对象可能需要先执行移动系统,然后再执行攻击系统,最后再执行死亡系统。工作流可以让这些系统按照一定的顺序来执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值