씬-레이어-오브젝트-컴포넌트 계층 구조
개요
자작 게임 프레임워크 구조는 씬(Scene) → 레이어(Layer) → 오브젝트(Object) → 컴포넌트(Component) 순으로 구성됐습니다. 객체지향 설계 원칙을 바탕으로 각 단계의 역할을 명확히 구분하며, 효율적인 관리와 유연한 확장성을 함께 제공합니다.
계층 구조 설계도
/Block-References/01_Game-Projcets/Self-Made-Game-Framework/Source/Scene-Layer-Object-Component-Hierarchy_Kor.png)
이 설계도는 각 클래스의 계층 구조를 시각적으로 보여줍니다.
클래스 목록 및 설명
⚠️ 참고: 씬-레이어-오브젝트-컴포넌트 계층 구조 설명을 위해 간소화한 코드입니다.
1. CScene 클래스
class CScene abstract { friend class CSceneManager; protected: CScene(); virtual ~CScene(); protected: std::vector<CLayer*> mLayers; protected: virtual bool Enter(void* payload = nullptr) = 0; virtual bool Exit() = 0; virtual void Update(float deltaTime); virtual void LateUpdate(float deltaTime); virtual void Render(SDL_Renderer* renderer); public: template <typename T, int initialCapacity = 50> T* InstantiateObject(const std::string& name, ELayer::Type type); };
- 역할:
- 모든 씬 클래스가 상속받는 추상 클래스입니다.
- 여러 레이어를 보유하며, 레이어는 배경, 오브젝트 등 순차적으로 그려야 하는 요소를 구분합니다.
- 핵심 함수들:
- CScene():
- 씬 생성자. 레이어를 메모리 풀에서 생성 및 초기화합니다.
- virtual ~CScene():
- 씬 소멸자. 레이어 메모리를 해제하되, 메모리 풀은 유지합니다.
- virtual void Update(float deltaTime):
- 씬 구성 요소(레이어, 충돌 시스템, 카메라, UI)를 업데이트합니다.
- virtual void LateUpdate(float deltaTime):
- 씬 구성 요소(레이어, 충돌 시스템, UI)를 지연 업데이트합니다.
- virtual void Render(SDL_Renderer* renderer):
- 씬 구성 요소(레이어, UI)를 렌더합니다.
- T* InstantiateObject<T, int>(const std::string& name, ELayer::Type type):
- 메모리 풀을 사용하여 오브젝트를 생성합니다.
- 오브젝트의 초기화 함수 성공시, 지정한 레이어 타입에 등록합니다.
- 오브젝트의 초기화 함수 실패시, 메모리를 다시 풀에 반환합니다.
- 메모리 풀을 사용하여 오브젝트를 생성합니다.
- CScene():
2. CLayer 클래스
class CLayer { friend class CScene; public: CLayer(); ~CLayer(); private: std::vector<class CObject*> mObjects; ESort::Type mSort = ESort::Y; protected: void Update(float deltaTime); void LateUpdate(float deltaTime); void Render(SDL_Renderer* renderer); public: void AddObject(CObject* obj) { mObjects.emplace_back(obj); } private: static bool SortY(CObject* objA, CObject* objB); };
- 역할:
- 레이어에 속한 모든 오브젝트를 관리하는 클래스입니다.
- 오브젝트를 순차적으로 업데이트, 지연 업데이트, 렌더하며 필요 시 Y축 정렬을 수행합니다.
- 레이어에 속한 모든 오브젝트를 관리하는 클래스입니다.
- 핵심 함수들:
- ~CLayer():
- 레이어 소멸자. 소속된 모든 오브젝트를 메모리 풀을 통해 해제합니다.
- void Update(float deltaTime):
- 오브젝트를 순차적으로 업데이트합니다.
- !Active 상태인 오브젝트는 제거 대상으로 표시합니다.
- !Enable 상태인 오브젝트는 업데이트를 건너뜁니다.
- 오브젝트를 순차적으로 업데이트합니다.
- void LateUpdate(float deltaTime):
- 오브젝트를 역순으로 지연 업데이트합니다.
- !Active 상태인 오브젝트는 제거 후, 메모리 풀에 반환합니다.
- !Enable 상태인 오브젝트는 지연 업데이트를 건너뜁니다.
- 오브젝트를 역순으로 지연 업데이트합니다.
- void Render(SDL_Renderer* renderer):
- Y축 정렬이 설정된 경우, 모든 오브젝트를 Y좌표 값 기준으로 1회 정렬합니다.
- 오브젝트를 순차적으로 렌더합니다.
- !Active 또는 !Enable 상태인 오브젝트는 렌더를 건너뜁니다.
- ~CLayer():
3. CObject 클래스
class CObject abstract : public CEntityBase { friend class CScene; friend class CLayer; protected: CObject(); virtual ~CObject(); protected: CScene* mScene; CLayer* mLayer; CComponent* mRootComponent; protected: virtual bool Init(); virtual void Update(float deltaTime); virtual void LateUpdate(float deltaTime); virtual void Render(SDL_Renderer* renderer); virtual void Release() = 0; public: CTransform* GetTransform() const { return mRootComponent->GetTransform(); } CComponent* GetComponent(const std::string& name = "") { if (name.empty()) return mRootComponent; size_t hashID = std::hash<std::string>()(name); return mRootComponent->FindComponent(hashID); } template <typename T> T* GetComponent() const { return mRootComponent->FindComponent<T>(); } template <typename T, int initialCapacity = 10> T* AllocateComponent(const std::string& name); };
- 역할:
- 씬과 레이어에 속하는 모든 오브젝트 클래스가 상속받는 추상 클래스입니다.
- 오브젝트는 최상위 컴포넌트
mRootComponent를 중심으로 컴포넌트 계층을 구성합니다.mRootComponent를 업데이트, 지연 업데이트, 렌더합니다.
- 핵심 변수:
CComponent* mRootComponent:- 오브젝트의 최상위 컴포넌트입니다.
- 오브젝트의 컴포넌트 계층 시작점이며,
CTransform을 포함입니다.
- 핵심 함수들:
- CObject():
- 오브젝트 생성자. 최상위 컴포넌트를 생성 및 초기화합니다.
- virtual ~CObject():
- 오브젝트 소멸자. 최상위 컴포넌트를 제거합니다.
- virtual void Init():
- 최상위 루트 컴포넌트의 초기화 함수를 호출합니다.
- virtual void Update(float deltaTime):
- 최상위 루트 컴포넌트의 업데이트 함수를 호출합니다.
- virtual void LateUpdate(float deltaTime):
- 최상위 루트 컴포넌트의 지연 업데이트 함수를 호출합니다.
- virtual void Render(SDL_Renderer* renderer):
- 최상위 루트 컴포넌트를 렌더합니다.
- T* AllocateComponent<T>(const std::string& name):
- 메모리 풀을 사용하여 컴포넌트를 생성합니다.
- CObject():
4. CComponent 클래스
class CComponent : public CEntityBase { friend class CObject; protected: CComponent(); virtual ~CComponent(); protected: size_t mTypeID = -1; CObject* mObject = nullptr; CTransform* mTransform = nullptr; CComponent* mParent = nullptr; std::vector<CComponent*> mChilds; protected: virtual bool Init(); virtual void Update(float deltaTime); virtual void LateUpdate(float deltaTime); virtual void Render(SDL_Renderer* renderer); virtual void Release(); public: CObject* GetObject() const { return mObject; } CTransform* GetTransform() const { return mTransform; } void AddChild(CComponent* child); bool DeleteChild(CComponent* child); private: CComponent* FindRootComponent(); CComponent* FindComponent(size_t id); template <typename T> T* FindComponent(); };
- 역할:
- 오브젝트의 실질적 기능을 수행하는 모든 컴포넌트가 상속받는 클래스입니다.
- 컴포넌트 계층 구조를 관리하며, 다른 컴포넌트를 자식으로 포함할 수 있습니다.
- 핵심 함수들:
- CComponent():
- 컴포넌트 생성자. 트랜스폼을 메모리 풀에서 생성 및 초기화합니다.
- virtual ~CComponent():
- 컴포넌트 소멸자. 모든 자식 컴포넌트와 트랜스폼을 메모리 풀에 반환합니다.
- virtual bool Init():
- 모든 자식 컴포넌트의 초기화 함수를 호출하며, 중간에 실패하면 false를 반환합니다.
- virtual void Update(float deltaTime):
- 컴포넌트를 순차적으로 업데이트합니다.
- !Active 상태인 컴포넌트는 제거 대상으로 표시합니다.
- !Enable 상태인 컴포넌트는 업데이트를 건너뜁니다.
- 컴포넌트를 순차적으로 업데이트합니다.
- virtual void LateUpdate(float deltaTime):
- 컴포넌트를 역순으로 지연 업데이트합니다.
- !Active 상태인 컴포넌트는 제거 후, 메모리 풀에 반환합니다.
- 이 과정에서 트랜스폼 계층 관계도 함께 정리됩니다.
- !Enable 상태인 컴포넌트는 지연 업데이트를 건너뜁니다.
- !Active 상태인 컴포넌트는 제거 후, 메모리 풀에 반환합니다.
- 컴포넌트를 역순으로 지연 업데이트합니다.
- virtual void Render(SDL_Renderer* renderer):
- 컴포넌트를 순차적으로 렌더합니다.
- !Active 또는 !Enable 상태인 컴포넌트는 렌더를 건너뜁니다.
- 컴포넌트를 순차적으로 렌더합니다.
- CComponent():
- 특징:
- 해당 컴포넌트 클래스는 계층 구조를 유연하게 구성할 수 있으며, 이미지는 그 예시를 보여줍니다.
/Block-References/01_Game-Projcets/Self-Made-Game-Framework/Source/Component-Hierarchy_Kor.png)
- 해당 컴포넌트 클래스는 계층 구조를 유연하게 구성할 수 있으며, 이미지는 그 예시를 보여줍니다.
맺는 말
씬-레이어-오브젝트-컴포넌트 계층 구조를 설계하면서 객체지향 설계 원칙을 실무적으로 적용하는 경험을 쌓을 수 있었습니다. 이를 통해 복잡한 게임 요소를 체계적으로 구성하고 관리하며, 유지보수와 확장이 한층 더 용이함을 확인했습니다.