1. State 패턴 개요

  • State 패턴이란?

    • 객체가 상태(State)에 따라 다른 동작을 수행하도록 설계.
    • 상태를 독립적인 단위로 관리해 코드의 복잡도를 줄이고 가독성을 높임.
  • 적용 사례

    • 게임 개발: 플레이어, 몬스터의 동작을 상태 기반으로 관리.
    • 장점:
      • 상태와 관련된 코드를 분리하여 유지보수성 향상.
      • 상태 변화 추적이 쉬움.

2. State 패턴 이론

  1. 상태 기반 설계의 원칙

    • 상태를 중심으로 동작을 정의.
    • 예: 몬스터의 상태
      • 로밍 → 피격 → 추적 → 벗어남 → 돌아감
    • 상태에 맞는 코드만 작성.
  2. 상태와 입력 함수 분리

    • 입력 처리 함수: 플레이어의 입력을 감지.
    • 상태별 함수: 상태에 따라 동작을 수행.
  3. 상태 변화 함수 작성

    • 상태가 변경되면 이를 함수로 처리.
    • 예: SetState 함수로 상태를 변경하고, 그에 따른 초기화 작업 수행.
  4. FSM(Finite State Machine)

    • 유한 상태 기계: 한 번에 하나의 상태만 가지도록 설계.
    • FSM을 꼭 사용할 필요는 없으나, 복잡한 시스템에서 유용.

3. 코드 분석

(1) 상태 정의

  • 플레이어의 상태를 enum으로 정의:
enum class PlayerState
{
	Idle,     // 대기 상태
	Move,     // 이동 상태
	Skill,    // 스킬 사용 상태
	JumpFall  // 점프 상태
};
  • 설명:
    • 플레이어의 모든 가능한 상태를 정의.
    • Idle, Move, Skill, JumpFall과 같은 명확한 상태 구분.

(2) 상태 설정 함수 (SetState)

void Player::SetState(PlayerState state)
{
	if (_state == state)
	{
		return; // 이미 동일한 상태면 무시
	}
	_state = state; // 상태 변경
}
  • 설명:
    • 상태가 변할 때만 값을 변경.
    • 중복 호출을 방지해 불필요한 계산을 줄임.

(3) 상태별 동작 처리 (Tick)

void Player::Tick()
{
	Super::Tick();

	switch (_state)
	{
	case PlayerState::Idle:
		TickIdle();
		break;
	case PlayerState::Move:
		TickMove();
		break;
	case PlayerState::Skill:
		TickSkill();
		break;
	}
}
  • 설명:
    • 현재 상태에 따라 적절한 동작 수행:
      • PlayerState::IdleTickIdle() 호출.
      • PlayerState::MoveTickMove() 호출.
    • 상태별 동작을 분리해 코드의 가독성과 유지보수성을 높임.

(4) 상태별 함수

void Player::TickIdle()
{
	// Idle 상태의 동작 정의
}

void Player::TickMove()
{
	// Move 상태의 동작 정의
}

void Player::TickSkill()
{
	// Skill 상태의 동작 정의
}
  • 설명:
    • 각 상태에 해당하는 동작을 함수로 작성.
    • 상태별로 독립된 코드 작성이 가능해 코드 중복과 복잡도를 줄임.

(5) 상태 변화와 충돌 처리

void Player::OnComponentBeginOverlap(Collider* collider, Collider* other)
{
	BoxCollider* b1 = dynamic_cast<BoxCollider*>(collider);
	BoxCollider* b2 = dynamic_cast<BoxCollider*>(other);

	if (b1 == nullptr || b2 == nullptr)
	{
		return;
	}

	AdjustCollisionPos(b1, b2);

	if (b2->GetCollisionLayer() == CLT_GROUND)
	{
		_state = PlayerState::Move; // 바닥에 닿으면 이동 상태로 변경
	}
}
  • 설명:
    • 충돌 시 상태 변화:
      • 충돌 대상이 바닥(CLT_GROUND)이면 Move 상태로 전환.
    • 상태 변화가 명확히 정의되어 있어 버그 발생 가능성을 줄임.

(6) 점프 상태 처리

void Player::Jump()
{
	if (_state == PlayerState::JumpFall)
	{
		return; // 이미 점프 중이면 무시
	}
	_state = PlayerState::JumpFall; // 상태 변경
	_speed.y = -500; // 위로 가속도 부여
}
  • 설명:
    • 점프 중(JumpFall)일 경우 중복 호출 방지.
    • 상태를 JumpFall로 변경 후 속도 변경.

profile
李家네_공부방

0개의 댓글