我正在实现一个实体组件系统,当我尝试向实体添加组件时遇到了麻烦。这样做的结构如下:
下面会找到一个ID为0的实体,并为其添加一个位置组件。
m_entityManager->addComponentToEntityID(0, ComponentManager::POSITION);
void EntityManager::addComponentToEntityID(unsigned int entityID, ComponentManager::ComponentType componentType)
{
std::shared_ptr<Entity> tempEntity;
for (unsigned int index = 0; index < m_maximumEntities; ++index)
{
if (m_entityVector[index].getEntityID() == entityID)
{
addComponentToEntity(std::make_shared<Entity>(m_entityVector[index]), componentType);
break;
}
}
}
以上只是首先找到Entity的辅助函数,然后它会调用下面的函数:
void EntityManager::addComponentToEntity(std::shared_ptr<Entity> entity, ComponentManager::ComponentType componentType)
{
if (entity != nullptr)
{
switch (componentType)
{
case ComponentManager::POSITION:
entity->addComponent(m_componentManager->getUnassignedPositionComponent());
break;
default:
break;
}
}
}
此函数将找到未分配(免费,可用,未添加到实体)位置组件并将其返回。
PositionComponent& ComponentManager::getUnassignedPositionComponent()
{
for (unsigned int index = 0; index < m_positionComponentVector.size(); ++index)
{
if (m_positionComponentVector[index].isAssigned() == false)
{
m_positionComponentVector[index].assign();
return m_positionComponentVector[index];
}
}
}
最后,在Entity中我们有这个功能:
void Entity::addComponent(Component& component)
{
m_componentVector.push_back(component);
}
实体保存在EntityManager内部的向量内,作为堆栈上的普通对象创建。对于ComponentManager内部的位置组件,这是相同的。
我的目标是将所有组件保留在ComponentManager和系统中,并向ComponentManager请求以某种方式处理组件。我想将每个实体的指针或引用保留到它拥有的组件中。
我的问题是,一旦Entity :: addComponent()完成,m_componentVector向量就不再保存添加到它的Component,就像它超出范围一样。我认为问题出在某个地方我传递副本而不是引用?我最初将参数作为指针,但正在尝试修复它。
答案 0 :(得分:1)
评论中的相关事实:Entity::m_componentVector
被定义为
std::vector<Component> m_componentVector;
这是一个存储Component
个对象的向量,而不是引用。因此,在Entity::addComponent
中,行
m_componentVector.push_back(component);
将复制component
引用的对象并将其添加到向量中。此副本独立于从。复制的对象。
更糟糕的是,component
addComponent
参数实际上引用了PositionComponent
类型的对象(可能是Component
派生的)。在制作上述副本时,只会复制与基类Component
对应的部分。这被称为切片 - 派生类添加的部分只是&#34;切掉&#34;。
您希望让实体m_componentVector
引用ComponentManager
中存储的组件。您无法在向量中存储引用。您可以存储指针,但是如果向向量添加了其他元素(即,如果存储指向m_positionComponentVector[0]
的指针),则可以使指向向量元素的指针无效,并且稍后会向m_positionComponentVector
添加更多元素。如果需要重新分配,您存储的指针将变为无效)。因此,存储指数是您最安全的选择。