몬스터 혹은 자동사냥 기능을 만들다보면 AI 작성은 꼭 필요하다.
그 중 많이 사용되는 FSM(유한기계상태)과 BT(행동트리) 중 이번에는 FSM에 대해 설명을 하려고한다.
FSM의
장점
1. 디버깅이 쉽다
2. 상태에 대한 코딩이 해당 상태에서만 작동하기 때문에 코드 작성이 쉽다.
3. 문제가 되는 상태만 수정하면 되기때문에 버그 수정이 쉽다.
단점
1. 상태의 규모가 커지면 복잡해진다.
2. 해당 상태에 대한 적용만 가능하다.
사실 위와같이 장단점만 작성하면 느낌이 잘 오지않는다.
예를들어
-IDLE (대기상태)
-ATTACK (공격상태)
-DEAD (사망상태)
3가지 상태가 있다고 가정하자.
"가만히 있는데 몬스터에게 맞아도 반격을 하지 않아요."
라는 버그제보가 들어왔다.
가만히 서있다는 것은 IDLE 상태를 뜻할 것이다.
그렇다면 난 IDLE 상태만 디버깅하면 버그를 쉽게 찾을 수 있을 것이다.
하지만
캐릭터가 ATTACK의 상태 규모가 클 경우
"공격을 하다가 공격을 끝내기도 전에 대기 상태로 계속 빠져요"
라는 버그가 제보가 들어오면
IDLE 상태로 바뀐다는 다는 버그를 찾을 수 있겠지만.
ATTACK의 규모가 너무 크기에 코드 리팩토링의 수준의 작업까지 진행 될 수도 있다.
(물론 코딩을 잘하면 되겠지만 여러명이 작업 하다보면 불가피한 상황이 발생할 수 있다)
느낀 장단점은 위와 같다.
그렇다면 FSM의 상세 설계는 사람마다 차이가 있겠지만
공통 형식은
1. 상태 진입
2. 상태 진행 중
3. 상태 탈출
3개를 기본 조건으로 작성한다.
상태(FSM)의 클래스
public abstract class FSMState<T> {
public abstract void Enter(T entity);
public abstract void Execute(T entity, float deltaTime);
public abstract void Exit(T entity);
}
Enter : 상태 진입
Execute : 상태 진행중
Exit : 상태 탈출
상태를 진행시키는 클래스
public class StateMachine<T>
{
private T Owner;
private FSMState<T> CurrentState;
public void Awake()
{
CurrentState = null;
}
public void Initialize(T owner, FSMState<T> state)
{
Owner = owner;
ChangeState(state);
}
public void Update(float _delta_time)
{
if (null != Owner)
{
if (null != CurrentState)
{
CurrentState.Execute(Owner, _delta_time);
}
}
}
public bool ChangeState(FSMState<T> NewState)
{
if (null == Owner)
{
return false;
}
if (null != CurrentState)
{
CurrentState.Exit(Owner);
}
CurrentState = NewState;
if (null != CurrentState)
{
CurrentState.Enter(Owner);
}
return true;
}
}
상태의 시작
1. 초기화 : Initailize
2. 상태 진행중 : Update
3. 상태가 변할 때
-기존 상태 탈출 : Exit
-현재 상태 변경
-현재 상태 시작 : Enter
위의 순서로 진행되는 것은 FSM의 기본으로 시작된다.
프로젝트마다 필요에 따라
상태 값이 바뀔때 이전 상태값을 저장해두는 방법도 있고
이전 상태값으로 Revert 시키는 방법도 있고
커스텀하기 나름이다.
'프로그래밍 > ETC' 카테고리의 다른 글
IntelliJ - Grep Console 을 소개합니다 (0) | 2023.09.01 |
---|---|
SDK와 API의 차이는 무엇인가요? (0) | 2022.08.21 |
데이터 관리 - Excel (0) | 2022.08.07 |
데이터 관리 - XML (0) | 2022.08.05 |
내 눈이 편한 코딩용 Font (1) | 2020.05.21 |