보스 제작(FSM)
이번에는 보스 몬스터를 제작했다. 네크로댄서의 데스메탈 보스를 구현해봤다.
필드 몬스터는 단순하게 이동->멈춤->이동->멈춤을 반복했다면
보스 몬스터는 좀 더 다양한 패턴이 존재한다.
보스 몬스터가 상황마다 어떻게 행동할지 명확하게 하기위해 이번엔 FSM을 이용해 보스 패턴을 구현했다.
데스메탈 보스는 처음에 방패를 들고 등장한다.
방패를 들었을땐 플레이어를 추적하며 이동하고, 방패를 든 방향에서 플레이어의 공격이 들어오면 피해를 입지 않고 몬스터를 소환한다.
일정이상 데미지를 입으면 방패는 사라지고, 그때부턴 플레이어에게서 멀어지는 방향으로 도망치기 시작한다.
일정 턴 도망친 후에는 몇턴간 몬스터를 소환하는 액션을 취하고, 소환이 끝나기 전에 공격하지 않으면 몬스터를 소환한다.
방패가 없을때 공격을 받으면 보스방 내부 랜덤한 위치로 순간이동 한다.
FSM
이제 FSM 구현을 보자.
보스의 상태 STOP, CHASE, FLEE, SUMMON 4가지를 가지게 했다.
한 순간 하나의 상태만을 가질 수 있도록 CurState 변수를 선언했다.
지난번 몬스터 제작때 플레이어가 이동하면 씬의 다른 모든 몬스터들도 행동 할 수 있도록 Step()이란 함수를 액터 클래스에 만들었었다. 보스 또한 플레이어가 이동할때마다 행동하게 된다.
보스는 한 순간에 하나의 상황(CurState)만 가지고 이 값에 따라 해당하는 함수를 호출하도록 하였다.
STOP상태는 보스가 방패를 들고있다면 다음턴에 플레이어를 추적하도록 CHASE 상태로 전환하고
방패가 없다면 도망가도록 FLEE상태로 전환한다.
CHASE 상태는 몬스터 제작때 구현했던 플레이어를 추적하는 방향을 정하는 SetDirection()함수를 호출한 후 이동에 성공하면 STOP상태로 전환한다.
FLEE 상태는 4칸을 도망친 후 몬스터를 소환하는 SUMMON상태로 전환한다.
도망칠때는 SetFleeDirection() 함수를 호출해 도망치는 방향을 정하고 이동에 성공했다면 STOP상태로 전환한다.
SUMMON 상태에선 이동하지 않고 3턴간 대기하며, 3턴이 지나면 몬스터를 소환하고 다시 FLEE상태로 전환한다.
방어하기
보스가 방패를 들었을땐 데미지를 입지 않고 몬스터를 소환한다.
액터들은 데미지를 입었을때 호출하는 TakeDamage 함수를 가지고 있는데, 보스는 데미지를 입었을때 방패를 들었을때와 들지 않았을때의 처리가 달라져야 한다. 따라서 이 함수를 오버라이드해서 구현했다.
보스가 특정 방향을 바라봤을때, 그 방향에 플레이어가 있는지 체크하는 CheckTowardPlayer함수.
예를들어 보스가 플레이어보다 오른쪽에 위치했다면, 보스가 왼쪽을 바라볼때 true를 반환한다.
도망가기
보스의 현재 위치와 플레이어의 위치를 가지고 도망갈 방향을 정한다.
더 이상 도망갈 방향이 없다면 그 위치에 멈춰있게 한다.
도망갈 방향이 존재하는지 판별하는 CanFlee 함수. 플레이어에게 멀어지는 방향으로 이동할 수 있는지 체크한다.
해당 방향에 벽이나 다른 액터가 있는지 조사해 이동 가능여부를 판별한다.
소환하기
몬스터를 소환하기 위해 몬스터 스폰 제작때 구현했던 MonsterSpawner 클래스를 사용했다.
보스 방 내부에 랜덤한 위치를 선택하고 해당 위치에 다른 액터가 없다면 몬스터를 소환한다.
순간이동
보스가 방패를 들지 않았을때 데미지를 받았을 경우 방 내부의 다른 위치로 순간이동 한다.
소환 중이었다면 소환을 취소하고 순간이동 하게 된다.
이것으로 보스 구현을 완성했다.