1
\$\begingroup\$

So,i'm having a bit of an issue with instantiating my gameobjects into to universe(My Scene object).

I can create an empty object from scratch and populate it from there with ease,my problem starts when i try to clone the gameobject which i just created.

My steps are

  1. I create an empty gameobject (GAMEOBJECT A)
  2. I add an component to it (COMPONENT A)
  3. Now i create a gameobject B from A
  4. GameObject B created,and the component A is in the component list of the gameobject B
  5. I try to get the component using inheritance but nullptr returns

It seems when i try to clone components,it returns only the base class pointer.There i try to recreate the derived class and add it to new gameobject's component list but obviously i fail.

  • If i cant solve this with inheritance how can i solve it ?
  • is there better way to implement such a desing ?
  • or i just fail to use inheritance in c++.If it's, can you guys point out what am i doing wrong here

This is my GameObject AKA RGameElement

class RGameElement
{
protected:
    vector<RElementComponent*> Elements;
public:
    template <class T>
    T* GetComponent() {

        int elementSize = Elements.size();

        for (int i = 0;i < elementSize;i++)
        {
            T* pr = dynamic_cast<T*>(Elements[i]);
            if (pr != nullptr)
                return pr;
        }
        return nullptr;
    }
    template <class T>
    T* AddComponent() {

        T* newElementComp = new T();
        Elements.push_back(newElementComp);
        return newElementComp;
    }
    void AddComponent(RElementComponent* targetComponent)
    {
        RElementComponent* newElement = new RElementComponent();

        *newElement = *targetElement;

        Elements.push_back(newElement);
    }

    /*void AddComponent(RElementComponent* targetComponent);*/
    vector<RElementComponent*> GetComponent() const;
}

This is my Component AKA RElementComponent

class RGameElement;

class RElementComponent
{
public:
    RGameElement* RootGameElement;
    virtual RElementComponent GetReference() { return RElementComponent(); };
    virtual void Setup() {};
    virtual void StartLogic() {};
    virtual void UpdateLogic() {};


}

and this my Instantiate via gameobject ref function

RGameElement* RUniverse::Instantiate(RGameElement* targetGameElement)
{
    RGameElement* newElement = new RGameElement();

    vector<RElementComponent*> components = targetGameElement->GetComponents();
    int componentSize = components.size();

    for (int i = 0;i < componentSize;i++)
    {
        newElement->AddComponent(components[i]);
    }

    Elements.push_back(newElement);
    return newElement;
}
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Please put that code as text. It's hard to read on mobile, we can't copy paste it easily, etc... \$\endgroup\$ – Vaillancourt Oct 18 '20 at 0:28
  • \$\begingroup\$ "It seems when i try to clone components,it returns only the base class pointer" sounds about right for C++. Create a virtual clone method. \$\endgroup\$ – Theraot Oct 18 '20 at 1:48
  • \$\begingroup\$ Your addcomponent method creates a generic component, so there is no way the more specific stuff will be copied over. I suggest you make your base component have a Clone(); method, as suggested by Theraot, and make it pure virtual (Clone () = 0;). \$\endgroup\$ – Vaillancourt Oct 18 '20 at 3:18
  • \$\begingroup\$ Thanks for your inputs it seems having a pure virtual Clone method solves my problem indeed,however i feel like i shouldnt write a Clone override for every component i create,Is there more automatic/dynamic way to implement this?.For example unreal engine seems to handling this stuff without the user defined Clone method in every actor we create.Vaillancourt from this time on i will post my code as a CODE not image thanks for feedback im new to this community :) \$\endgroup\$ – Roveldo Oct 18 '20 at 8:38
0
\$\begingroup\$

I managed to solve it with the help of the comments.

It seems i needed a interface to copy the derived object's data.

So

  • Created a pure virtual function inside a base class Clone()
  • Implemented that virtual function inside the derived class

Code looks like this

Base Element Class

class RElementComponent
{
public:
    RElementComponent* RootGameElement;
    virtual RElementComponent* Clone() = 0;
    virtual void Setup() {};
    virtual void StartLogic() {};
    virtual void UpdateLogic() {};

};

Derived class

class RObserver : public RElementComponent
{
public:
    int myOb;
    RObserver();
    void WhoAreYou();
    RObserver* Clone() 
    {
        RObserver* observer = new RObserver();
        *observer = *this;
        return observer;
    }
};

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I'm having a hard time understanding the Clone() method. When you set observer to this, what happens with the original pointer to the instance you create with new? Won't that cause a memory leak? \$\endgroup\$ – Daniel_1985 Oct 18 '20 at 12:57
  • \$\begingroup\$ I use Clone() when i need a copy of an object in the scene.For example there is a monster object in my scene and i want to spawn a monster identical to former one,so i duplicate the monster gameobject's components and inject to the new gameobject AKA RGameElement im my engine.Because this object is also added to the scene hierarchy when the time comes its removed from the memory. \$\endgroup\$ – Roveldo Oct 18 '20 at 15:01
  • \$\begingroup\$ @Daniel_1985 it's not setting observer to this, but *observer to *this. In other words, the contents of the pointee are copied, the pointer is left alone. But this should still use std::unique_ptr rather than a naked new. \$\endgroup\$ – Quentin Oct 19 '20 at 12:51
  • \$\begingroup\$ Thanks both of you for the explanations. \$\endgroup\$ – Daniel_1985 Oct 19 '20 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.