2

シミュレーション用のエンティティ コンポーネント システム設計を行おうとしています。これが今私を混乱させているものです。エンティティクラスを作成しようとしています

Entity.h
class Entity
{
public:
    Entity();
    virtual ~Entity() = 0;
    //---------------------Methods---------------------//
    void AddComponent(const shared_ptr<Component> component);

    template<class T>
    T* GetComponent() const;

    //---------------------Members---------------------//
    vector<shared_ptr<Component>>   m_components;
}

Entity.cpp
template<typename T>
T* Entity::GetComponent() const
{
    Component::component_type_t typeIndex = /*T::component_type*/
    T* returnPtr = dynamic_pointer_cast<T>(m_components[component_type].get());
    return returnPtr;
}

コンポーネントクラスは次のようになります

class Component
{
public:
    Component();
    virtual ~Component() = 0;
    //---------------------Methods---------------------//

    //---------------------Members---------------------//
    typedef enum component_type_t
    {
        MESH_T,
        RIGIDBODY_T,
        TRANSFORM_T,
        NUM_TYPES
    };
    component_type_t componentType;
};

私が使いたい方法GetComponent()はUnity3Dと同じです

Transform* t = GetComponent<Transform>()

しかし、ご覧のとおり、私はまだそれを行う方法を見つけることができません。私がかつて行っていた方法は、

class Entity
{
    .....
    Component* GetComponent(Component::component_type_t componentType) const
    {
      return m_components[component_type].get()
    };
}

そして、私はそれを次のようにしか使用できませんでした

Transform* t = dynamic_pointer_cast<Transform>(GetComponent(Component::component_type_t::TRANSFORM_T));

明らかに面倒です。

だから私の質問は、これとして何らかのフォームを使用できますか?

class Entity
{
    .....
    template<class T>
    T* GetComponent() const
    {
    Component::component_type_t typeIndex = /*T::component_type*/
    T* returnPtr = dynamic_pointer_cast<T>(m_components[component_type].get());
    return returnPtr;
    };
}

すべてのコンポーネント ポインターを格納するために使用し続けるためのクリーンさと速度を感じstd::vector<>ますが、それも有効な設計ですか?

4

1 に答える 1

3

昔、似たようなことをした。あなたはこれを難しい方法でやっていると思います。以下のコードは、必要に応じて簡単に変更できます。はComponents継承されます。継承を削除して、クラス内のクラスまたはクラス内のすべてのコンポーネント クラスに置き換えることができますComponent

#include <iostream>

struct Vector3
{
    float x, y, z;
    Vector3(float x, float y){}
    Vector3(float x, float y,float z){}
};

template <class T>
class Component
{
public:
    T t;
    void adNewComponent(){

    }
};

class Mesh{
public:
    Mesh(){}
};

class Rigidbody{
public:
    Rigidbody(){}
    void AddForce(float x,float y, float z){}
    void AddForce(Vector3 force){}
};


class Transform{
public:
    Transform(){}
};

class Object{

};

class GameObject:Object,
    Component<Mesh>,
    Component<Rigidbody>,
    Component<Transform>
{
public:
     template <class T>
     T &GetComponent()
    {
        return this->Component<T>::t;
    }

     template <class T>
     T &AddComponent(){
         this->Component<T>::adNewComponent();
         return this->Component<T>::t;
     }
};


int _tmain(int argc, _TCHAR* argv[])
{

    GameObject gameObject;
    gameObject.AddComponent<Rigidbody>();
    Rigidbody rigidBody = gameObject.GetComponent<Rigidbody>();
    rigidBody.AddForce(9,0,0);

    std::cin.get();
    return 0;
}
于 2016-06-01T23:57:26.217 に答える