如何处理实体的初始化和破坏

我一直在使用ECS模式,随着游戏复杂性的增加,我开始对实体初始化和破坏代码的时间有问题。

我将以物理学为例,但同样的原则也适用于大多数其他方面。

首先几个定义:

  • PhysicsModule – 低级物理系统(通常是一个像box2d的外部库) – 不知道ECS
  • PhysicsSystem – ECS系统 – 作为低级模块与ECS其余部分之间的接口
  • EntityWorld – 负责创建和销毁实体并将其关联到系统的对象

例如,一个典型的情况是这样的:

  • 1)实体从外部数据创建(Transform,ShapeData,CollidableData)
  • 2)数据必须注册到PhysicsModule(使用ShapeData和CollidableData)
  • 3)每一帧,PhysicsSystem向PhysicsModule询问相关对象的位置并更新变换。 重复一段时间。
  • 4)实体在另一个系统被毁坏的方式很远
  • 5)PhysicsModule需要被告知去除关联的物理对象

有问题的步骤是2)和5)。 我可以想到处理这个问题的两种方法。


让PhysicsSystem处理生命周期。

优点:

  • 逻辑被封装在一个系统中

缺点:

  • PhysicsSystem需要知道初始数据(ShapeData,CollidableData),在用PhysicsModule初始注册之后它是无用的
  • EntityWorld必须跟踪哪些实体被新鲜地添加或从系统中移除以通知它们
  • 必须推迟对实体的破坏,以使其组成部分仍然可以在同一框架内获得
  • 这种方法往往会导致长时间的事件链(跨越几帧),这是难以遵循的

为了使这个工作,主循环总是最终成为一个完整的混乱,以确保特定的inits,更新和销毁按正确的顺序完成。


所有的init和destroy代码都有一个地方。

优点:

  • init数据不会在初始注册之后使用
  • init / destroy代码在一个地方
  • 所有的清理工作都可以按正确的顺序在一个框架内完成

缺点:

  • 这基本上成为上帝的对象,并知道游戏中的一切
  • 整个事情可能变得非常混乱,所有可能的排列
  • 必须推迟对实体的破坏,以使其组成部分仍然可以在同一框架内获得

目前我的游戏已经演变成第一个解决scheme,而且我遇到了很多问题,所以我正在考虑尝试另一种方法。 我提到的第二个看起来好一点,但确实涉及一个上帝对象,从我的经验来看,这是一个不好的做事方式。

另外,我看了一下ECS的各种实现,并注意到其中一些方法有通知系统的实体被添加/删除的方法,其中一些没有 – 所以显然有不同的方法。

我的问题是 – 是否有另一种处理实体初始化和破坏的方法,而不诉诸上帝对象或神环?

在另一篇文章中,我从自己的回答中查看这个答案。

另一方面,我不清楚你的意思是什么God object ,但Factory模式是完全正确的。 除了集中初始化/销毁实体之外,还可以避免在经常创建/销毁的情况下创建对象。 我会解释一下:

您可以创建一个实体池,并且已经创建了每种types的实体的X个实例。 他们是工厂内部的对象,没有其他人必须知道他们, 直到他们需要一个新types的对象到工厂。 然后,你只需要用正确的参数初始化实体,但是你避免了内存分配(昂贵的)和对象构造本身。 这是工厂的责任,工厂的用户不知道,也不担心其实体是新建还是重新使用。

希望能帮助到你。