개발일지

보스 제작(FSM)

conmoto 2020. 4. 29. 10:19

이번에는 보스 몬스터를 제작했다. 네크로댄서의 데스메탈 보스를 구현해봤다.

 

필드 몬스터는 단순하게 이동->멈춤->이동->멈춤을 반복했다면

보스 몬스터는 좀 더 다양한 패턴이 존재한다.

보스 몬스터가 상황마다 어떻게 행동할지 명확하게 하기위해 이번엔 FSM을 이용해 보스 패턴을 구현했다.

 

 

데스메탈 보스는 처음에 방패를 들고 등장한다. 

방패를 들었을땐 플레이어를 추적하며 이동하고, 방패를 든 방향에서 플레이어의 공격이 들어오면 피해를 입지 않고 몬스터를 소환한다.

 

방패를 든 방향으로 공격하면 방어하고 몬스터를 소환한다.

일정이상 데미지를 입으면 방패는 사라지고, 그때부턴 플레이어에게서 멀어지는 방향으로 도망치기 시작한다.

일정 턴 도망친 후에는 몇턴간 몬스터를 소환하는 액션을 취하고, 소환이 끝나기 전에 공격하지 않으면 몬스터를 소환한다.

방패가 없을때 공격을 받으면 보스방 내부 랜덤한 위치로 순간이동 한다.

방패가 없을땐 도망치며 일정턴 도망치면 몬스터 소환을 시작한다.

FSM

이제 FSM 구현을 보자.

보스의 상태 STOP, CHASE, FLEE, SUMMON 4가지를 가지게 했다.

한 순간 하나의 상태만을 가질 수 있도록 CurState 변수를 선언했다.

데스메탈 보스는 STOP, CHASE, FLEE, SUMMON. 이 4가지 상태를 가진다.

 

지난번 몬스터 제작때 플레이어가 이동하면 씬의 다른 모든 몬스터들도 행동 할 수 있도록 Step()이란 함수를 액터 클래스에 만들었었다. 보스 또한 플레이어가 이동할때마다 행동하게 된다.

보스는 한 순간에 하나의 상황(CurState)만 가지고 이 값에 따라 해당하는 함수를 호출하도록 하였다.

보스는 한 순간 하나의 상태만을 가지고 이에 따라 행동한다.

 

STOP상태는 보스가 방패를 들고있다면 다음턴에 플레이어를 추적하도록 CHASE 상태로 전환하고

방패가 없다면 도망가도록 FLEE상태로 전환한다.

STOP 상태 행동

 

CHASE 상태는 몬스터 제작때 구현했던 플레이어를 추적하는 방향을 정하는 SetDirection()함수를 호출한 후 이동에 성공하면 STOP상태로 전환한다.

CHASE 상태 행동

 

FLEE 상태는 4칸을 도망친 후 몬스터를 소환하는 SUMMON상태로 전환한다.

도망칠때는 SetFleeDirection() 함수를 호출해 도망치는 방향을 정하고 이동에 성공했다면 STOP상태로 전환한다.

FLEE 상태 행동

 

SUMMON 상태에선 이동하지 않고 3턴간 대기하며, 3턴이 지나면 몬스터를 소환하고 다시 FLEE상태로 전환한다.

SUMMON 상태 행동

 

방어하기

보스가 방패를 들었을땐 데미지를 입지 않고 몬스터를 소환한다.

액터들은 데미지를 입었을때 호출하는 TakeDamage 함수를 가지고 있는데, 보스는 데미지를 입었을때 방패를 들었을때와 들지 않았을때의 처리가 달라져야 한다. 따라서 이 함수를 오버라이드해서 구현했다.

 

데미지를 입었을때 호출되는 TakeDamage 함수를 오버라이드.
방패를 들었을땐 Defense 함수를 호출해 방어 여부를 판별하고 방어에 실패한 경우만 데미지를 입는다.
방패를 든 방향에서 공격받으면 몬스터를 소환한다.

 

보스가 특정 방향을 바라봤을때, 그 방향에 플레이어가 있는지 체크하는 CheckTowardPlayer함수.

예를들어 보스가 플레이어보다 오른쪽에 위치했다면, 보스가 왼쪽을 바라볼때 true를 반환한다.

인자로 받은 방향에 플레이어가 있는지 체크하는 함수.

도망가기

보스의 현재 위치와 플레이어의 위치를 가지고 도망갈 방향을 정한다.

더 이상 도망갈 방향이 없다면 그 위치에 멈춰있게 한다.

더 이상 도망갈 방향이 없다면 그 자리에 멈춰있는다.

 

플레이어로부터 멀어지는 방향으로 랜덤하게 정한다.

도망갈 방향이 존재하는지 판별하는 CanFlee 함수. 플레이어에게 멀어지는 방향으로 이동할 수 있는지 체크한다.

해당 방향에 벽이나 다른 액터가 있는지 조사해 이동 가능여부를 판별한다.

해당 방향으로 이동할 수 있는지 체크하는 함수

 

소환하기

몬스터를 소환하기 위해 몬스터 스폰 제작때 구현했던 MonsterSpawner 클래스를 사용했다.

생성자에서 소환할 몬스터를 저장.

보스 방 내부에 랜덤한 위치를 선택하고 해당 위치에 다른 액터가 없다면 몬스터를 소환한다.

몬스터 소환 함수.

 

순간이동

보스가 방패를 들지 않았을때 데미지를 받았을 경우 방 내부의 다른 위치로 순간이동 한다.

소환 중이었다면 소환을 취소하고 순간이동 하게 된다.

방패를 들지 않은경우 데미지를 입으면 순간이동 한다.
순간이동 함수.

 

이것으로 보스 구현을 완성했다.