상태 의존적인 컴포넌트 기반 게임 오브젝트 간략 정리 아키텍처 이야기

얼마전부터 붙잡고 있는 상태 의존적인 컴포넌트 기반 게임 객체에 대해 이야기를 해보려고 합니다.

상태 의존적인 컴포넌트 기반 게임 객체 라는것은 제가 이름을 붙여놓은거라.. 엄청 대단하거나 한게 절대 아닙니다.

상태 의존적이다?

먼저 '상태 의존적인' 이라는 말을 붙힌 이유에 대해 말해보자면

제가 설계중인 게임 객체의 기본은 모든 객체는 어떠한 상태를 반드시 가진다. 라는것에서부터 시작됩니다.

저번에도 잠깐 언급했지만 상태 의존적인 컴포넌트 기반 게임 객체는

컴포넌트 기반 게임 객체 + 상태기계의 완전한 결합 입니다.

컴포넌트 기반 게임 객체나 FSM은 이미 많이 사용되고 있는 것이고

AI를 만들게 되면 거의 대부분 FSM으로 만들게 되니 어차피 게임 객체는 대부분의 경우 상태기계를 사용하게 되기 마련입니다.

단지 저는 이 보편적으로 사용되는 두녀석을 완전히 결합시켜버린것 뿐입니다.

어찌보면 요즘 기능별로 많이 나눠서 여기 저기 붙여서 사용해야 한다는 개념이 많이 퍼져있으니

시대를 역행하는것 일지도 모르죠. 컴포넌트 기반 이라는 녀석도 그런 생각에서 나온 것이니까요.

어쨌든 기본은 상태기계 없는 게임 객체는 존재하지 않는다는 것입니다.

어차피 모든 게임 객체는 상태를 가져야 하고 그렇다면 굳이 나눠놓을 필요가 없다고 생각합니다.

합쳐놓은 형태에서 좀 더 이점을 얻어보자는것이 목표입니다.

게임객체는 일반 컴포넌트들과 특수한 컴포넌트인 명령자와 상태기계를 가집니다.

먼저 일반적인 컴포넌트들은 기능만을 가지고 있습니다. 컴포넌트들끼리 서로 엉켜서 다른 컴포넌트에 접근을 한다던지

다른 컴포넌트에 메시지를 보내고 받고 하면서 어떠한 처리를 하는 로직을 가지지 않습니다.

정말 단순하게 기능만을 가집니다. 그리고 그 기능들을 명령자와 행동들이 사용합니다.

그래서 명령자와 행동에서 필요한 컴포넌트에 접근을 하기 위해 컴포넌트들은 RTTI를 구현하여 사용해야 할 것 같습니다.

이제 상태 의존적인 게임 객체의 핵심인 상태기계에 대해서 설명을 할 차례입니다.

상태기계는 상태와 행동을 관리합니다. 그렇다면 상태는 뭐고 행동은 뭘까요?

먼저 상태는 사전에서 찾아보면 사물ㆍ현상이 놓여 있는 모양이나 형편. 이라는 뜻입니다.

예를 들면 '서있음' '앉아있음' '걸음' '공격' '맞음' '쓰러짐' 등 명사를 의미합니다.

행동도 역시 사전에서 찾아보면 몸을 움직여 동작을 하거나 어떤 일을 함.라는 뜻입니다.

예를 들면 '서다' '앉다' '걷다' '공격하다' '맞다' '쓰러지다' 등 동사를 의미하죠

이제 다시 상태와 행동 사이의 관계를 정리하면 상태가 표현되는 것이 행동 입니다.

상태 의존적인 게임 객체에서 상태는 데이터, 행동은 상태를 표현하기 위한 객체로 관리됩니다.

즉 상태는 문자열이나 열거형 또는 정수형 등으로 관리되고

행동은 각각 행동 하나하나가 하나의 클래스 또는 하나의 스크립트로 구현된다는 것을 의미합니다.

해당 상태의 시작부터 끝까지를 표현하는 것이기에 복잡하지 않고

그렇기 때문에 스크립트로 구현하기가 쉽습니다. 또 스크립트를 C++로 쉽게 옮길 수 있습니다.

상태와 행동에 대해서는 어느정도 설명을 하였고.. 이제 이 상태와 행동을 관리하는 상태기계 차례입니다.

상태기계는 상태와 행동을 하나의 쌍으로 관리합니다. 상태에 행동 연결( 상태, 행동 ); 이런 느낌이죠

C++ 코드로 보면 BindAction( "Attack", new PlayerAttack() ); 정도가 될 것 같습니다.

한가지 중요한 것은 상태에 연결된 행동은 동적으로 다른 행동으로 변경이 가능하다는 것입니다.

유주얼 서스펙트를 예로 들어보면, 처음 설정은 BindAction( 걸음, 다리를 절면서 걷는다 ); 로 되어있고

시나리오상 경찰서에서 나오면서 트리거가 작동되면 BindAction( 걸음, 정상적으로 걷는다 ); 이런식으로 말이죠

좀 더 게임스럽게 실제 구현했던 사례를 예로 들어 보자면..

Espada de alma에 존재했던 좀비 몬스터 중에는 이런 녀석이 있었습니다.

처음에는 느리게 걸어다니면서 몽둥이를 휘두르던 몬스터였는데

데미지를 받아서 HP가 30% 이하가 되고 특정 조건이 만족되면 

다리가 떨어지면서 팔로 엄청 빠르게 이동하면서 점프를 하여 입으로 물어뜯는 공격을 하는 몬스터였죠

이 몬스터는 굉장히 쉽게 구현이 되었습니다.

이전 회사에서 작업했던거라 자세히 기억은 안나지만.. 대충 이런식이었습니다.

처음 설정은 
BindAction( 이동, 몬스터기본이동 );
BindAction( 공격, 몬스터기본공격 );

데미지를 입어서 조건이 만족되면
BindAction( 이동, 좀비상체이동 );
BindAction( 공격, 좀비물어뜯기공격 );

추가로 코딩이 필요했던것은 '좀비상체이동' 과 '좀비물어뜯기공격'에 해당하는 행동뿐이었습니다.

상태기계에는 상태 계층 시스템 이라는것을 구현하는것이 좋을것 같습니다.

현재 가지고 있는 상태와 새로 입력된 상태가 만났을때 어떤 상태를 가져야 하는지를 결정하기도 하고

어떤 상태끼리 만났을때는 두가지 이상의 상태를 동시에 가져야 할 경우도 있기 때문입니다.

이것을 계층구조로 관리를 하면 동시에 두가지 이상의 상태를 가지고 있어도 레벨이 높은 상태가 존재하겠죠

이런 상태기계는 여러개가 존재할 수 있습니다. 하지만 그 중 활성화된 상태기계는 하나만 존재하고

실제로 객체가 상태를 가질때에는 활성화된 상태기계를 사용합니다.

이제 마지막으로 명령자에 대한 설명만 남았습니다.

명령자가 하는 역활은 간단합니다. 객체에 어떤 상태를 가져야 하는지 명령을 내리는 역활을 합니다.

객체는 상태 명령과 해당 상태를 표현할 때 사용되는 데이터를 받아서 움직이게 되겠죠

명령자는 유저입력, AI 스크립트, 컷씬 스크립트, 네트워크 등에 의한 명령자들이 존재하고

각각 역활에 맞게 객체에 명령을 보내 움직이도록 합니다.

물론 객체는 명령을 받는 인터페이스가 따로 존재해야 합니다. 명령자는 이 인터페이스를 사용할테고요

그 이유는 자의에 의해 상태를 가지는 경우와 타의에 의해 상태를 가지는 경우가 존재하기 때문입니다.

즉, 명령자는 자의에 의해 상태를 가지는 경우를 담당한다고 볼 수 있습니다.

명령자에 의해 처리되는 상태 명령은 이동, 공격 같은 것들입니다. 

(다른 객체에 부딪혀서)밀림, (다른 객체에게)맞음 같은 것들은 명령자와는 따로 처리되어야 합니다.

하나의 객체는 여러개의 명령자를 가질 수 있고 상황에 맞게 하나의 명령자가 활성화되어 실행됩니다.

로컬 플레이어 같은 경우에는 유저입력 명령자로 움직이다가

퀘스트나 레벨등에 의해 트리거가 작동하여 컷씬명령자로 교체되고

컷씬이 끝나면 다시 유저입력 명령자로 돌아가는 형태입니다.


참고로 아직 완전히 구현해본적이 없기 때문에 이 내용은 계속 변할 수 있습니다..

핑백

  • 끼로 : 완벽하진 않지만 MMORPG 설계, 우리도 도전! 2011-04-09 18:10:52 #

    ... pplication에서는 어떤 모듈을 어떤 구현을 사용하여 실행할 것인지등을 설정하고 각 시스템들을 실행시키고 관리하는 프로젝트. 게임 객체 설계는 상태 의존적인 컴포넌트 기반 게임 객체 간략 정리 를 참고.. 마지막으로 Execution! Execution 레이어에서는 실제 실행파일의 프로젝트들이 들어간다. 각 실행파일의 형태에 따라 ... more

  • 끼로 : 게임 오브젝트 설계 이야기 2011-04-21 23:01:09 #

    ... ada de alma 입니다. 타겟 시장이 한국이 아닌 페루/베네수엘라를 중심으로 한 남미 지역이었기 때문에 한국에서 오픈한적은 없지요.. 연결된 내용 -> 상태 의존적인 컴포넌트 기반 게임 객체 설계 ... more

  • 끼로 : 게임 오브젝트 설계 이야기 2011-04-21 23:04:16 #

    ... ;이라고나 할까요.. 어쨌든 꽤 깔끔하게 정리가 되어가고 있어서 다행이라고 생각중입니다 ..ㅎㅎ 자세한 내용은 좀 더 정리가 되면 그때.. 연결된 내용 -> 상태 의존적인 컴포넌트 기반 게임 객체 설계 ... more

덧글

  • 소민 2011/04/03 00:22 # 삭제 답글

    무슨소린지는 모르겠는데 이 블로그는 마치 어둠의 다크에 묻혀 혼돈의 카오스에 빠져 기적의 미라클을 바라는 절망의 디스페어 같은 느낌 이야.
  • 끼로 2011/04/03 00:23 #

    ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
  • 준혁 2011/04/04 01:17 # 삭제 답글

    혹시 리눅스와 네트워크와 os와 해킹에 관해서 강의를좀..ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ으엌ㅋㅋㅋㅋㅋㅋ
    리눅스 5번째갈아먹음 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
  • 끼로 2011/04/04 09:51 #

    안타깝게도 리눅스는 만져본적도 없어 ㅠㅠㅠㅠㅠ 해킹도 해본적도 없고 ㅠㅠㅠㅠㅠ 안티 해킹은 라키온때 열심히 하긴 했는데.. 고마워 덕분에 카테고리 하나 더 늘릴게 생각났네..
  • M. Kim 2011/04/05 21:31 # 삭제

    해킹=핵+ing=즉, 핵을 쏘는 중

    고스트를 뽑으면 되겠네요.
  • 끼로 2011/04/05 21:33 #

    M. Kim // 고마워
  • 크앙 2011/04/04 11:26 # 삭제 답글

    나에게 전설이 아닌 리전드 따위의 악플을 기대하지 말어.
  • 시체 2011/04/04 13:24 # 삭제 답글

    아 재미없다.
  • denoil 2011/04/04 13:32 # 삭제 답글

    아 이게 뭔소리야 샘플보여줘 ㅋㅋㅋ
  • 끼로 2011/04/04 13:33 #

    그런거 없어요 ㅋㅋ
  • 귀거리님 2011/04/04 15:40 # 삭제 답글

    오 링크 감사!!끼로 천재님!!!ㅋㅋㅋㅋ
  • 끼로 2011/04/04 16:05 #

    덜덜 PD님 여기서 이러시면 곤란해요
  • 아르틴 2011/04/04 19:44 # 삭제 답글

    글 잘쓰네...쵝오~!!
  • 래스 2011/04/05 10:16 # 삭제 답글

    뭐라는거야
  • CreamNuts 2011/04/10 21:49 # 삭제 답글

    유한상태기기..
  • 2018 2018/09/29 12:13 # 삭제 답글

    2018년에 보시는분? ㅋ
댓글 입력 영역