I am trying to code my first game engine in C++ which will be like how Unity's scripting works. I am trying to make a component system. Here is my problem:
I want to have a vector containing my component since I will maybe need to add some dynamically. Where the problem happens is when I want to add derived class of my Component class. Here is an example:
std::vector<Component*> components;
With this line I cannot do this (which I would love to be able to do):
gameObject.GetComponent<TextRenderer>().text [...]
I still need to learn a lots and sincerely I do not understand totally the part of this (I don't understand templates and can't find a good tutorial) code but here is my GetComponent function:
template<typename T>
inline T* GetComponent()
{
for (int i = 0; i < components.size(); i++)
if (typeid(components[i]) == typeid(T))
{
std::cout << "Found Component." << std::endl;
return (T*) &components[i];
}
}
This function does not works it return nothing and/or have conversion problem.
I think that C-style conversion is undefined behavior.
As far as I know, all the component class(like SpriteRenderer, Rigidbody and so on) derive from Component
in Unity. So we can use dynamic_cast
which offers safe downcasting. If the casting succeeds it returns a valid pointer otherwise nullptr
.
Here's an example of how I'd implement it.
template<typename T>
inline T* GetComponent()
{
for (int i = 0; i < components.size(); i++)
{
T* downcasted = dynamic_cast<T>(components[i]);
if (downcasted)
{
std::cout << "Found Component." << std::endl;
return downcasted;
}
}
return nullptr; // Unity's GetComponent returns null when not found
}
And please also note that dynamic_cast
is relatively slow, just in case you care about the performance really seriously.