gpt4 book ai didi

c++ - 如何最好地管理游戏引擎中的组件?

转载 作者:搜寻专家 更新时间:2023-10-31 02:12:53 24 4
gpt4 key购买 nike

所以我在开发我的第一个游戏引擎时遇到了瓶颈。目前我有一个实体基类,它有一个组件指针 vector ,它将保存指向某些系统管理器类(graphisManager、PhysicsManager 等)中的组件对象的指针。这是我当前的实体 header (经过精简以专注于主要问题):

实体.h

class Component;

namespace BlazeGameWorld
{
class Entity
{
public:
BlazeFramework::Math::Vector2D position;

protected:
Vector<Component*> components;

static BlazeGraphics::GraphicsManager graphicsManager;
static BlazePhysics::PhysicsManager physicsManager;
static BlazeInput::InputManager inputManager;
//....other managers

private:

///////////////////////////////////////////////////////////////////////

public:
Entity();
~Entity();

virtual bool Initialize();
virtual bool Shutdown();

virtual void Update() = 0;

void AddComponent(Component* p_component);

//Part of the broadcast messaging system for components to be able
//to talk to one another in a decoupled way.
void SendMessage(uint messageID);

protected:

private:
};
}

如您所见,我们的想法是使用静态 SystemManager 类来管理指向堆上实际组件的指针。这是潜在的 PhysicsManager 类的粗略标题(其他管理器类也类似):

物理管理器.h

class PhysicsComponent;

namespace BlazePhysics
{
class PhysicsManager
{
public:

protected:
int numPhysicsComponents;
private:
Vector<PhysicsComponent*> physicsComponents;

/////////////////////////////////////////////////////////////

public:
PhysicsManager();
~PhysicsManager();

bool Initialize();
bool Shutdown();

void Update();

template <typename PhysicsComponentType>
PhysicsComponentType* CreatePhysicsComponent();

private:
};

//template definitions
template <typename PhysicsComponentType>
PhysicsComponentType* PhysicsManager::CreatePhysicsComponent()
{
PhysicsComponentType* physicsComponent = new PhysicsComponentType
physicsComponents.push_back(physicsComponent);

return physicsComponents.at(numPhysicsComponents++);
}
}

因此我可以将所有不同的 physicsComponent 指针存储在 PhysicsManger vector 中(指向 CollisionComponents、PositionComponents 等的指针)。问题是如果我想调用特定于特定物理组件的方法,我无法编译。例如,如果(在 PhysicsManager 的更新循环中)我想在每一帧更新 collisionComponent 的 CheckCollision() 方法,我不能只在 for 循环中说 physicsComponents.at(i).CheckCollision 因为编译器在编译时不知道 CollisionComponent 是什么。有没有办法首先推断数组中组件的类型,然后如果它与 CollisionComponent 匹配则调用 CheckCollision 方法?还是有更好的实现方式,因为这看起来有点笨拙?

最佳答案

实体不应该知道您的系统,它们应该只是组件的集合。否则,引入另一个引擎系统的过程也需要更改实体类,这违背了 ECS 的整体目的。

系统也不应该管理组件。一个系统可能使用多个组件,许多系统可能使用,例如位置/碰撞几何组件。

所以,在我看来:

  • 理想情况下,组件应该是简单的纯数据类,而所有处理都在系统内完成。
  • 实体必须只提供一种添加和删除组件的方法,并且告诉它是否有特定的组件。
  • 某种实体管理器必须以缓存友好的方式存储组件以便系统访问它们,并且应该能够提供一个实体列表,这些实体具有特定的组件/标签集给系统。

这样,例如,如果你想为某些实体添加脚本行为,你所要做的就是添加 ScriptComponentScriptingSystem。您现有的所有代码都不需要任何更改。

This question有很多关于该主题的非常有用的资源。

关于c++ - 如何最好地管理游戏引擎中的组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42105138/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com