游戏设计模式初学:面向数据编程下的ECS框架

引用自:云风的 BLOG: 浅谈《守望先锋》中的 ECS 构架

(仅是简单总结,方便个人理解,以原文内容为准)

先下定义:ECS(Entity Component System)是一个gameplay层面的框架,主要解决如何建立一个模型来处理游戏对象(game object)的更新操作。

传统框架:传统的很多游戏引擎是基于面向对象来设计的,游戏中的东西都是对象,每个对象有一个叫做 Update 的方法,框架遍历所有的对象,依次调用其 Update 方法。有些引擎甚至定义了多种 Update 方法,在同一帧的不同时机去调用。

ECS的目的:解决传统游戏引擎中,对把不同的业务模块聚合在一起的对象做处理时,容易导致模块的内聚性差,模块间也会出现不必要的耦合。

比如如何用预测技术做更准确的网络同步。网络同步只关心很少的对象属性,没必要在设计同步模块时牵扯过多不必要的东西。为了准确,需要让客户端和服务器跑同一套代码,而服务器并不需要做显示,所以要比较容易的去掉显示系统;客户端和服务器也不完全是同样的逻辑,需要共享一部分系统,而在另一部分上根据分别实现……

总的来说、需要想一个办法拆分复杂问题,把问题聚焦到一个较小的集合,提高每个子任务的内聚性。

ECS的详细解释 :

E:指的是Entity,即传统引擎中的Game Object。但在ECS框架下,他仅仅指的是C(componment)的组合。主要负责生命周期

 C和S:框架的核心。C是指componment(组件),S指system(即系统/模块)。

对于游戏来说,每个模块应该专注于干好一件事,而每件事要么是作用于游戏世界里同类的一组对象的每单个个体的,要么是关心这类对象的某种特定的交互行为。

比如碰撞系统,就只关心对象的体积和位置,不关心对象的名字,连接状态,音效、敌对关系等。

它也不一定关心游戏世界中的所有对象,比如那些不参与碰撞的装饰物。

所以对每个子系统来说,筛选出系统关心的对象子集以及只给它展示它所关心的数据就是框架的责任了。

ECS的大致结构:

一个游戏对象(E)由数个其所需要的属性的组件(C)组合而成。如一个角色对象,由其名字,位置状态等数据的Component组成。

一个模块(S)管理一个固定组件(C)的组合,即由数个特定的组件(C)组合成的游戏对象(E)。例如一个System可以筛选出所有由名字,位置信息,生命值,连接状态的组件(C)组合而成的游戏对象(E),如果E只有位置信息,名字,没有另外两个组件(C),这个组件就不会被System筛选并管理。

在演讲中,作者谈到了一个根据输入状态来决定是不是要把长期不产生输入的对象踢下线的例子,就是要对象同时具备连接组件输入组件等,然后这个 AFK 处理系统遍历所有符合要求的对象时,根据最近输入事件产生的间,把长期没有输入事件的对象通知下线。

他特别说到,AI 控制的机器人,由于没有连接组件,虽然具备状态组件,但不满足 AFK 系统要求的完整组件组的要求,就根本不会遍历到,也就不用在其上面浪费计算资源了。

这是 ECS 相对传统对象 Update 模型的一点优势;用传统方法的话,很可能需要写一个空的 Update 函数。

 ECS的编写思路:

每个system独立开发,遍历他所需要的组件的合集,是一种纯方法的组合,内部没有状态,仅关注他所需要的数据的相关处理。

(system之间不需要相互调用,降低耦合游戏,由世界外部框架驱动若干的system。

gamplay编程则是粘合这些system,只需要关心每个system做了什么,对哪些Component造成了影响,并且正确书写这些system更新次序。。

你可能感兴趣的:(unity)