대난투 팀 프로젝트(Project_CS) - 2

정완훈·2025년 4월 4일

언리얼 엔진 게임 모드/상태 설계: 로비부터 튜토리얼까지

게임 개발 초기, 특히 로비, 캐릭터 선택, 실제 게임 플레이 등 다양한 단계를 가진 게임에서는 GameMode와 GameState의 역할을 명확히 하는 것이 중요하다. 여기서는 메인 메뉴, 싱글 플레이 로비, 튜토리얼 단계를 위한 GameMode/GameState 설계 과정을 정리한다.

1. 기본 구조: ACSGameModeBaseACSGameStateBase

먼저 공통 로직을 처리할 기반 클래스를 정의한다.

  • ACSGameModeBase (AGameMode 상속):
    • MatchType (Single, Coop, Versus), MatchPhase (Waiting, Playing, Finished) 같은 기본 상태 관리.
    • BeginPlay에서 GameInstance로부터 MatchType을 읽어 InitMatchLogic 호출.
    • PostLogin 등 기본적인 플레이어 관리 오버라이드 포인트 제공.
    • HandleStartGame, HandleEndGame으로 MatchPhase 변경 및 GameState에 전파 (SetMatchPhase 함수).
  • ACSGameStateBase (AGameStateBase 상속):
    • MatchPhase 등 리플리케이트되어야 하는 게임 전체 상태 저장.
// CSGameModeBase.h 예시 일부
UCLASS()
class CS_API ACSGameModeBase : public AGameMode
{
    // ... MatchType, MatchPhase 변수 ...
    virtual void BeginPlay() override;
    virtual void InitMatchLogic(); // MatchType 따라 다른 초기화 호출
    void SetMatchPhase(EMatchPhase NewPhase); // GameState에도 반영
};

// CSGameStateBase.h 예시 일부
UCLASS()
class CS_API ACSGameStateBase : public AGameStateBase
{
    UPROPERTY(Replicated) EMatchPhase MatchPhase;
    // ...
};

2. 메인 메뉴: CSMainMenuGameMode

  • 역할: 메인 메뉴 레벨 관리, 선택된 MatchType에 따라 다음 레벨 로드.
  • 특징:
    • AGameMode 직접 상속 (Base 불필요).
    • UI 표시는 PlayerController의 책임. GameMode는 UI 클래스를 가지지 않는다.
    • TryStartMatch 함수: GameInstanceMatchType 확인 후 OpenLevel 호출 (튜토리얼 또는 로비).
    • PostLogin: 플레이어 접속 시 로그 남기기 외 특별한 역할 없음 (UI는 PlayerControllerBeginPlay에서).

3. 싱글 플레이 로비/캐릭터 선택: CSSingleLobbyGameMode, CSSingleLobbyGameState

  • 역할: 싱글 플레이 전용 로비 관리, 캐릭터 선택 처리, 튜토리얼 레벨 이동 요청.
  • CSSingleLobbyGameMode (AGameMode 상속):
    • 생성자: GameStateClass = ACSSingleLobbyGameState::StaticClass(); 설정.
    • RequestStartTutorial: PlayerController로부터 호출됨. 핵심 역할은 아래 두 가지.
      1. (구현 필요) 선택된 캐릭터 정보(TSubclassOf<APawn>)를 GameInstance 또는 PlayerState에 저장.
      2. UGameplayStatics::OpenLevel로 튜토리얼 레벨 로드.
  • CSSingleLobbyGameState (AGameState 상속):
    • 로비 관련 상태 저장 (현재는 특별한 내용 없음).
    • (선택적 구현) 선택 가능한 캐릭터 목록(AvailableCharacterClasses) 저장 및 리플리케이트 가능.

4. 튜토리얼: CSTutorialGameMode, CSTutorialGameState

  • 역할: 튜토리얼 레벨의 게임 규칙 및 상태 관리.
  • CSTutorialGameMode (ACSGameModeBase 상속):
    • 생성자: GameStateClass = ACSTutorialGameState::StaticClass(); 설정.
    • GetDefaultPawnClassForController: (구현 필요) 로비에서 GameInstance/PlayerState에 저장된 SelectedCharacterClass 정보를 읽어와 리턴. 실패 시 FallbackDefaultPawnClass 사용.
    • HandleStartingNewPlayer, RestartPlayer: 플레이어 스폰 후 MakePlayerInvulnerable 호출.
    • MakePlayerInvulnerable: 플레이어 Pawn의 SetCanBeDamaged(false) 호출하여 무적 처리.
    • PlayerEnteredStageTransitionZone: (레벨 액터 호출 필요) 레벨 내 트리거 액터가 호출하면 StageLevelName에 지정된 다음 레벨 로드.
  • CSTutorialGameState (ACSGameStateBase 상속):
    • CurrentObjectiveText (FText, ReplicatedUsing=OnRep): 현재 목표 텍스트 저장 및 클라이언트 전파.
    • bIsTutorialComplete (bool, Replicated): 튜토리얼 완료 여부 플래그.
    • SetCurrentObjectiveText, CompleteTutorial: 서버 전용 함수 (GameMode가 호출).
    • OnRep_CurrentObjectiveText: 클라이언트에서 목표 텍스트 변경 감지 시 호출됨. (UI 업데이트 로직 구현 필요).

5. 연결 흐름 및 핵심 구현 포인트

  • 로비 -> 튜토리얼:
    1. 로비 UI (PlayerController) -> 서버 RPC (Server_RequestStartTutorial, 선택 캐릭터 정보 전달) -> ACSPlayerController.
    2. 서버 RPC (ACSPlayerController) -> CSSingleLobbyGameMode::RequestStartTutorial 호출.
    3. CSSingleLobbyGameMode -> 선택 정보 저장 (GameInstance 또는 PlayerStateSelectedCharacterClass 변수 구현 필요) -> OpenLevel.
  • 튜토리얼 스폰:
    1. CSTutorialGameMode::GetDefaultPawnClassForController -> 저장된 정보 읽기 (GameInstance/PlayerStateSelectedCharacterClass 변수 구현 필요) -> Pawn 클래스 리턴.
    2. HandleStartingNewPlayer/RestartPlayer -> Pawn 스폰 및 SetCanBeDamaged(false).
  • 튜토리얼 UI 업데이트:
    1. CSTutorialGameMode -> 튜토리얼 진행 -> CSTutorialGameState::SetCurrentObjectiveText 호출.
    2. CSTutorialGameState -> CurrentObjectiveText 변경 및 리플리케이트.
    3. 클라이언트 CSTutorialGameState -> OnRep_CurrentObjectiveText 호출.
    4. OnRep_CurrentObjectiveText -> 로컬 ACSPlayerControllerUpdateTutorialObjectiveUI 함수 호출 (구현 필요).
    5. ACSPlayerController -> TutorialWidgetInstance의 텍스트 업데이트 함수 호출 (구현 필요).
  • 튜토리얼 -> 스테이지:
    1. 레벨 트리거 액터 (BP_StageTransitionTrigger구현 필요) -> 플레이어 감지 -> CSTutorialGameMode::PlayerEnteredStageTransitionZone 호출.
    2. CSTutorialGameMode -> OpenLevel (미리 설정된 StageLevelName).

0개의 댓글