【发布时间】:2020-05-14 02:05:08
【问题描述】:
我正在制作一个游戏引擎,目前我正在研究实体组件系统。下面是一些代码以便更好地理解:
class Entity {
public:
...
void AddComponent(EntityComponent component, unsigned int id){
m_Components.insert({id, component});}
EntityComponent GetComponent(unsigned int id)
{
auto i = m_Components.find(id);
ASSERT(i != m_Components->end()); // ASSERT is a custom macro
return i->second;
}
private:
...
std::unordered_map<unsigned int, EntityComponent> m_Components;
};
也是一个简单的父类EntityComponent,它只处理ID(我跳过了一些代码,因为它在这个问题中无关紧要):
class EntityComponent {
public:
...
private:
unsigned int m_EntityID;
size_t m_PoolIndex;
};
而且是孩子。其中之一是 TransformComponent:
class TransformComponent : public EntityComponent {
public:
TransformComponent(unsigned int entityID, unsigned int poolID = 0, glm::vec2 position = glm::vec2(1.0,1.0), glm::vec2 scale = glm::vec2(1.0,1.0), float rotation = 0) : EntityComponent(entityID, poolID),m_Rotation(rotation), m_Scale(scale), m_Position(position){}
inline glm::vec2 GetPosition() { return m_Position; }
inline glm::vec2 GetScale() { return m_Scale; }
private:
glm::vec2 m_Position;
float m_Rotation;
glm::vec2 m_Scale;
};
所以问题是我想创建一个实体,向它添加一个 TransformComponent 并使用它的函数 GetPosition()、GetScale()。
创建实体并添加 TransformComponent 是可行的,但是当我想使用 GetComponent(id) 时,它会返回父类 EntityComponent,因此这意味着我不能使用 GetPosition() 等函数。
如何更改代码,以便将 EntityComponent 的不同子级添加到 unordered_map 并使用它们的 ID 接收它们并使用它们的公共方法?
【问题讨论】:
-
您可能想要
std::unordered_map<unsigned int, std::unique_ptr<EntityComponent>>之类的东西。 (或其他智能指针) -
object slicing 有问题。
-
我赞同@Jarod42 的评论。此外,查询派生类型的基指针列表的一种直接方法是使用visitor pattern。不过,我的建议是将 ECS 样板和管道留给像这样的库:github.com/skypjack/entt,因为你有一个游戏要做。
标签: c++ inheritance parent-child subclass entity-component-system