현재 상태에 따라 다른 동작을 수행하도록 컨트롤러의 동작을 상태패턴을 이용해서 만들었습니다.
유휴 상태(IdleState), 추적상태(ChaseSate), 공격상태(AttackState), 디버프 상태(DebuffState), 죽음 상태(DeadState)를 만들었습니다.
본 포트폴리오의 상태 패턴은 아래와 같이 구성되어 있습니다.

전투 시 컨트롤러는 현재 자신의 상태를 판단하여 동작을 수행합니다. 아래는 전투 캐릭터의 컨트롤러 클래스입니다. 자신의 상태를 파악해서 수행해야하는 상태를 리턴하는 메서드입니다.
// ORDER : #3) 현재 상태에 따라 컨트롤러의 동작을 변경하는 상태패턴 구현
private IState CheckState()
{
if (battleStatus.isDead)
// 나는 죽어있는가?
{
return deadState;
}
if (battleStatus.currentState == CombatState.Actunable)
// 행동 불가 상태인가?
{
return debuffState;
}
if (!SetTarget(out target))
// 다른 적이 있는가?
{
return idleState;
}
if (attack.isAttack)
// 공격중인가?
{
return attackState;
}
if (movement.MoveDistanceResult(target.transform))
// 적과의 거리가 나의 공격 사거리보다 먼가?
{
return chaseState;
}
else
{
//타겟이 살아있는가?
if (!target.battleStatus.isDead)
{
if (attack.canAttack)
// 공격할 수 있는가?
return attackState;
}
}
return idleState;
}
그리고 매 프레임마다 자신의 상태를 체크하고 수행합니다.
private void Update()
{
// 전투중인가?
if (BattleManager.Instance == null) return;
if (BattleManager.Instance.currentBattleState != BattleSceneState.Battle) return;
// 현재 상태를 판단합니다.
stateContext.SetState(CheckState());
// 현재 상태의 동작을 수행합니다.
stateContext.Update();
}
스테이트 컨텍스트는 현재 상태를 동작하거나 새로운 상태로 변경합니다. 그리고 Behaviour Tree의 Action Node를 참고해서 상태의 동작을 Start, Update, End로 세분화 해서 동작하도록 만들었습니다.
StateContext.cs
public void Update()
{
// 현재 상태가 있다면 현재 상태를 진행합니다.
if(CurrentState != null)
CurrentState.OnUpdate();
}
// 새로운 상태를 등록한다.
public void SetState(IState state)
{
if (CurrentState == state)
// 현재 상태와 동일한 상태가 들어온다면 리턴
{
return;
}
if(CurrentState != null)
// 현재상태와 다른 상태 혹은 null 값이 들어왔다면
// 현재 상태의 종료 메서드를 호출합니다.
CurrentState.OnEnd();
// 상태를 변경해줍니다.
CurrentState = state;
// 변경된 상태의 시작 메서드를 호출합니다.
CurrentState.OnStart();
}
아래는 이동 상태 예시입니다.
MoveState.cs
public class ChaseState : State,IState
{
private Movement movement; // 이동 행동
public ChaseState(Controller controller) : base(controller)
{
movement = controller.movement;
}
public void OnEnd()
{
// 이동이 종료되면 이동 애니메이션을 종료하고 네브메쉬를 초기화합니다.
movement.isMove = false;
controller.animator.ResetTrigger("Move");
movement.ResetNav();
}
public void OnStart()
{
// 이동이 시작되면 AI상태를 추적상태로 변경해주며, 이동 애니메이션으로 변경합니다.
controller.currentAIState = AIState.Chase;
movement.isMove = true;
controller.animator.SetTrigger("Move");
}
public void OnUpdate()
{
// 대상위치로 이동합니다.
movement.MoveNav(controller.target.transform);
}
}'Portfolio > Portfolio_RiseTheTower' 카테고리의 다른 글
| #6) 현재 무기 외형에 따라 나올 애니메이션 컨트롤러를 변경 (0) | 2023.07.26 |
|---|---|
| #5) 현재 자신의 위치에서 가장 가까운 컨트롤러를 반환하는 함수 (0) | 2023.07.26 |
| #4) 제네릭 형식 제약조건을 사용한 장비아이템 데이터를 가져오는 함수 (0) | 2023.07.26 |
| #2) 오브젝트 풀 사용 예시 (0) | 2023.07.26 |
| #1) 싱글턴 패턴 사용 예시 (0) | 2023.07.26 |