정글에서 온 개발자
12/27 TIL 게임 객체 모델의 종류 본문
클래스 계층 구조
모든 게임 객체가 하나의 기본 클래스를 상속하는 구조. 이 때문에 모놀리식 클래스라고 부르기도 한다.
class Actor
{
public:
virtual void Update(float deltatime);
virtual void Draw();
}
//나머지 객체들이 모두 Actor를 상속한다.
class Player : public Actor
{
public:
void Update(float deltatime) override;
void Draw() override;
}
단점
객체들이 쓸데 없는 메소드를 상속 받거나, 이를 피하기 위해 계층 구조가 복잡해질 수 있다.
컴포넌트로 구성된 게임 객체
유니티가 이 방식을 채택했다.
게임객체는 다른 객체로부터 상속받지 않고, 기능을 구현한 컴포넌트를 컬렉션으로 가지고 있다.
이를 위해 추가 제거 메서드가 있다. (이 메서드'만' 있다)
class GameObject
{
public:
void AddComponet(Component *comp);
void RemoveComponent(Component *comp);
private:
std::unordered_set<Component*> mComponents;
}
컴포넌트 추적 시스템 구축은 따로 필요하다. (예를들어 DrawComponent를 등록해 관리하는 Renderer 객체가 있다)
단점
컴포넌트들 간의 의존성이 명확하지 않다.
이 때문에 GameObject가 다른 컴포넌트를 가지고 있는지 질의(DrawComponent를 위해 TransformComponent 질의)해야 해, 성능 병목이 있다.
하이브리드(컴포넌트와 계층 구조로 구성)
언리얼 엔진 4에서 이런식으로 한다.
Actor
컴포넌트 리스트는 여전히 가지고 있다.
Actor 클래스가 많이 쓰는 기본적인 요소 (위치, 비율, 회전) 등은 가지고 있게 한다. (컴포넌트가 변환데이터에 바로 접근)
active, pause, dead 상태를 가지고 Game이 이를 통해 Actor를 관리한다.
Actor가 다른 Actor 생성을 위해 Game을 의존성 주입 받는다.
Component
Component 클래스는 해당 클래스를 소유하는 Owner를 의존성 주입받는다.
갱신 순서도 전달받는다. 순서유지를 위해 Actor의 AddComponent는 컴포넌트를 정렬한다.
기타 다른 접근법
- 인터페이스 클래스 사용
- 컴포넌트가 완전히 제거된, 컴포넌트 모델의 확장 방법 (숫자로 컴포넌트를 추적하는 컴포넌트 데이터베이스 활용)
- 객체를 속성으로 정의
참고 서적
Game Programming in C++ , 산자이 마드하브 https://product.kyobobook.co.kr/detail/S000001804867
느낀점
컴포넌트로 구성한 게임객체 파트에서, 유니티에서 비효율적으로 보였던 코드가 왜 그렇게 작성돼야 하는지 이해가 됐다.
하이브리드 스타일에서 액터를 추가할 때, pendingList를 사용하고, 제거할 때 deadList를 사용했는데 pintOS에서 스케줄링을 할 때 쓰레드를 다루는 방식과 닮아있어서 흥미로웠다.
'TIL' 카테고리의 다른 글
12/28 TIL 좋은 단위 테스트의 4대 요소 (1) | 2024.12.29 |
---|---|
12/28 TIL 단위 테스트의 구조 (1) | 2024.12.28 |
12/27 TIL 클린 아키텍처 15장~22장 (2) | 2024.12.28 |
12/26 TIL XCode, C++ snippet (0) | 2024.12.27 |
12/26 TIL 단위 테스트 1장~2장 (3) | 2024.12.26 |