I'm having trouble figuring out a way to make a component based engine architecture in c++. But i cant figure out a way to combine a vector of components with a class that derives from component.
I want to override components virtual function. But the only way i can make it call the overrided function is to make the component-derived class a pointer, but i want every gameobject to contain its own components in a vector and not outside the class as a pointer.
I tried to remove as much unnecessary code as possible.
My structure:
//GameObject class, contains components and other objects
class GameObject
{
public:
GameObject(){}
~GameObject(){}
void AddChild(GameObject child)
{
children.push_back(child);
}
void AddComponent(Component component)
{
components.push_back(component);
}
void Input(){}
void Update(){}
void Render()
{
for(unsigned int i = 0; i < components.size(); i++)
components[i].Render();
}
private:
std::vector<GameObject> children;
std::vector<Component> components;
};
//base class component
class Component
{
public:
Component(){}
~Component(){}
virtual void Input(){}
virtual void Update(){}
virtual void Render(){ cout << "Component -> Render()" << endl; }
};
class MeshRenderer : public Component
{
public:
MeshRenderer(Mesh _mesh, Material _material)
{
mesh = _mesh;
material = _material
}
~MeshRenderer(){}
//override components virtual Render()
void Render(Transform transform)
{
mesh.Render(material);
cout << "MeshRenderer -> Render()" << endl;
}
private:
Mesh mesh;
Material material;
};
GameObject* root = new GameObject();
MeshRenderer meshRenderer(mesh, material);
root->AddComponent(meshRenderer);
//GameLoop
while(!quit)
{
root->Render();
}
Looks like you want to pass your objects by reference, use
to avoid any slicing.
For proper usage with
std::vector<>
's and polymorphic inheritance, you'll need smart pointers, e.g.std::unique_ptr<Component>
to preserve ownership, orstd::shared_ptr<Component>
for shared ownership (raw pointers asComponent*
might work as well, but are far harder to manage correctly).or
and accordingly
or
It depends on your actual use cases if these
Component
instances should be uniquely owned by their aggregating parentGameObject
class, or not.To use
std::shared<>
pointers, that could expire outside their usages scope you may consider usingstd::weak_ptr<>
.As mentioned, it totally depends on your use cases, and how you want these aggregated components being accessible from outside of the
GameObject
class.