posted by REDFORCE 2017. 3. 14. 10:21

엔진 코어를 제작하기 위해 여러 자료들을 찾아다니고 


병렬 프로그래밍부터 시작해서 객체지향적인 구조를 설계해야하는가? 등등 공부해온 결과



현재 많은 게임사들이 쓰고있고 시도하고있는 


Component Based GameObject 구조 방식을 도입해보려고 합니다.



현재 까지 만들어두었던 June_Engine의 방식은 객체지향 구조에


1 Processor - 1 Thread.


Initialize -> Update -> Render 순으로 동작하는 로직이었습니다만


이 구조를 조금 다듬어 보았습니다.

[아직 시도중일 뿐 완전하진 않습니다!]


render / update 루프를 돌게 되는 모든 객체들을 GameObject라 명하고 Component를 기반으로 작성됩니다.


그러면 대표적인 Component를 살펴보겠습니다.


RenderComponent / Physics Component / AI Component / Network Component / Position Component / Animation Component 등...


이름만 봐도 알 수 있듯이 어떤 행위 자체를 수행하게 되는 함수들을 일련의 컴포넌트라 칭합니다.

(그러나 함수 자체에 어떤 객체와 같은 의의를 두는 것!)


그리고 컴포넌트들이 탑재 되어 있는 어떤 행동 주체가 되는 "객체"(?) 를 Game Object라 부를 수 있습니다.



게임을 위한 엔진이니 게임을 예로 들어보면 


1. 플레이어 캐릭터를 만든다. 이 플레이어 캐릭터는 GameObject를 상속받은 하나의 객체입니다.

2. 몬스터 캐릭터를 만든다. 이 몬스터 캐릭터는 GameObject를 상속받은 하나의 객체입니다.


여기서 플레이어/ 몬스터 캐릭터는 동일한 캐릭터라는 성질을 갖고 있기 때문에


캐릭터 라는 Class를 생성하고 GameObject를 상속받는 구조로 만들면 되겠군요.



그래서 이 GameObject와 Component를 대체 어떤식으로 만드는가?

우리는 먼저 Component를 먼저 정의할 필요가 있습니다.



아래의 코드를 살펴보면서 주요 부분을 열거해서 적도록 하겠습니다.


1. ComponentBase Class는 현재(this) Component의 주인이 될 Owner GameObject* 를 갖고 있습니다.

2. ComponentBase Class는 추상 클래스 입니다.

3. 순수 가상함수로 componentID / familyID 가 있습니다.

4. Component 들이 사용 할 virtual 가상함수들이 내포되어 있습니다.



다음 GameObject Class 입니다.

[Entity를 상속받은 점은 신경안쓰셔도 됩니다]


1. 자기 자신의 고유 id 값이 있습니다 ( m_Id )

2. GameObject Class 안에는 Component TABLE 이 있습니다. ( m_Components )

3. 생성자에서 무조건 id 값을 받도록 되어있습니다.

4. familyId를 이용하여 자신이 갖고있는 components에서 해당 컴포넌트를 찾을 수 있습니다.



cpp 파일이야 뭐...헤더에 선언 해뒀던 내용 그대로 구현 되었을 뿐입니다.


다만 저도 아직 햇갈리는 점은 GameObject::setGOC ( ComponentBase * newGOC ) 함수에서


m_Components에서 componentID 값으로 비교를 하는게 맞나?

라는 의문이듭니다.


familyId도 있지 않았나...?응?응???

하는 뒤숭숭한게 있습니다만 정확히 저도 gpg 6 를 다시 정독해보고 확인하면 수정하도록 하겠습니다.







[GitHub(Gist) - Component.h / .cpp]


[GitHub(Gist) - GameObject.h / .cpp]