我已经为FPS设计了一个实体系统。它基本上是这样的:
我们有一个“世界”对象,称为GameWorld。它包含一个GameObject数组以及一个ComponentManager数组。
GameObject拥有一个Component数组。它还提供了一个非常简单的事件机制。组件本身可以向实体发送事件,该事件将广播到所有组件。
Component基本上是赋予GameObject某些属性的东西,并且由于GameObject实际上只是它们的容器,因此与游戏对象有关的所有事情都发生在Components中。示例包括ViewComponent,PhysicsComponent和LogicComponent。如果需要它们之间的通信,可以通过使用事件来完成。
ComponentManager只是一个类似于Component的接口,对于每个Component类,通常应该有一个ComponentManager类。这些组件管理器负责创建组件,并使用从XML文件之类读取的属性来初始化它们。
ComponentManager还负责组件的大量更新,例如PhysicsComponent,我将在其中使用外部库(该库一次执行世界上的所有操作)。
为了实现可配置性,我将为实体使用一个工厂,该实体将读取XML文件或脚本,创建文件中指定的组件(这还将在正确的组件管理器中添加对它的引用以进行批量更新),以及然后将它们注入GameObject对象。
现在出现了我的问题:我将尝试将其用于多人游戏。我不知道该如何处理。
首先:客户从一开始就应该拥有哪些实体?我首先要说明单人引擎如何确定要创建的实体。
在关卡编辑器中,您可以创建“画笔”和“实体”。刷子用于墙壁,地板和天花板等事物,基本上是简单的形状。实体是我告诉过您的GameObject。在关卡编辑器中创建实体时,可以为其每个组件指定属性。这些属性直接传递给实体脚本中的类似构造函数的对象。
保存要加载的引擎的级别时,它会分解为实体及其关联属性的列表。画笔将转换为“ worldspawn”实体。
当您加载该级别时,它只是实例化所有实体。听起来很简单,是吗?
现在,对于实体的联网,我遇到了许多问题。首先,从一开始就应该在客户端上存在哪些实体?假设服务器和客户端都具有关卡文件,则客户端可能会实例化该关卡中的所有实体,即使它们只是出于服务器上的游戏规则而存在。
另一种可能性是,客户端在服务器发送有关实体的信息后立即实例化该实体,这意味着客户端将仅具有其所需的实体。
另一个问题是如何发送信息。我认为服务器可以使用增量压缩,这意味着它仅在发生变化时才发送新信息,而不是在每帧都向客户端发送快照。尽管这意味着服务器必须跟踪每个客户端当前所知道的信息。
最后,应该如何将网络注入引擎?我在考虑一个组件NetworkComponent,它被注入到每个应该联网的实体中。但应该如何在网络组件知道什么变量网络,以及如何访问这些,最后如何在客户端上相应的网络组件应该知道如何改变网络变量?
我在处理此问题时遇到了很大的麻烦。如果您能帮助我,我将不胜感激。我也欢迎有关如何改进组件系统设计的提示,因此不要害怕提出建议。