[DAY74] Game Flow : Title Level & Server Join

베리투스·2025년 12월 1일

TIL: Today I Learned

목록 보기
63/93
post-thumbnail

지금까지는 에디터에서 플레이 버튼을 누르면 자동으로 서버에 접속되는 방식이었다. 하지만 실제 배포될 게임은 '타이틀 화면'에서 IP를 입력하고 접속하는 과정이 필수적이다.

오늘은 타이틀 전용 레벨과 게임모드를 별도로 제작하여 수동으로 서버에 접속하는 기능을 구현하고, 레벨이 바뀔 때 필수적으로 처리해야 하는 입력 모드(Input Mode) 전환 이슈를 해결했다.


📌 오늘의 목표

  • Title Level 전용 GameMode(Pawn 없음)와 PlayerController(UI 전용) 구현
  • OpenLevel 함수를 사용한 IP 직접 접속(Direct Connection) 구현
  • Input Mode 전환: UI Only(타이틀) \rightarrow Game Only(인게임)

📚이론 및 원리

1. 타이틀 화면의 아키텍처 (GameMode 분리)

타이틀 화면은 캐릭터가 총을 쏘는 게임 월드가 아니다. 따라서 인게임용 GameMode를 그대로 쓰면 불필요한 캐릭터가 스폰되거나 HUD가 뜨는 문제가 생긴다.
따라서 타이틀 전용 가벼운 GameMode를 따로 만들어야 한다.

  • TitleGameMode: DefaultPawnNone으로 설정 (캐릭터 스폰 방지).
  • TitlePlayerController: BeginPlay에서 바로 로그인 위젯을 띄우고, 마우스 커서를 보이게 설정(bShowMouseCursor = true).

2. 서버 접속의 핵심 : OpenLevel

클라이언트가 특정 서버로 이동하는 함수는 UGameplayStatics::OpenLevel이다. 여기에 접속하려는 IP 주소를 넣으면 엔진이 해당 서버로 여행(Travel)을 떠난다.

💡 Network Tip:

  • 127.0.0.1 (Localhost): 혼자 테스트할 때는 자신의 컴퓨터를 가리키는 루프백 주소인 127.0.0.1을 입력하면 된다.
  • Port 7777: IP 뒤에 별도 포트를 적지 않으면 언리얼 기본 포트인 :7777로 접속을 시도한다.
// [DXTitlePlayerController.cpp]
void ADXTitlePlayerController::JoinServer(const FString& InIPAddress)
{
    if (InIPAddress.IsEmpty()) return;

    // 입력받은 IP 주소를 이름(FName)으로 변환
    FName NextLevelName = FName(*InIPAddress);
    
    // 해당 주소로 레벨 이동 (Absolute = true 옵션으로 IP 접속)
    UGameplayStatics::OpenLevel(GetWorld(), NextLevelName, true);
}

3. 접속자 관리 : PostLogin

플레이어가 OpenLevel을 통해 서버에 도착하면, 서버의 GameMode에서는 PostLogin 함수가 호출된다.
이 시점은 "플레이어의 전송이 완료되고, 서버에 온전한 PlayerController가 생성된 직후"이다.

  • 활용: 접속 환영 메시지 전송, 생존자 리스트 추가, DB 로딩 시작 등.

4. 트러블 슈팅: 입력 모드 전환 (Input Mode)

가장 많이 하는 실수 중 하나다. 타이틀에서는 마우스를 쓰기 위해 UIOnly 모드를 썼는데, 게임 레벨로 넘어가서도 이 모드가 유지되어 캐릭터가 움직이지 않는 버그가 발생했다. ⚠️
레벨이 바뀌면 반드시 입력 모드를 게임용으로 초기화해줘야 한다.

// [DXPlayerController.cpp] - 게임용 컨트롤러
void ADXPlayerController::BeginPlay()
{
    Super::BeginPlay();

    // 로컬 플레이어(내 화면)인 경우에만 입력 모드 설정
    if (IsLocalController())
    {
        // 다시 게임 조작 모드로 변경 (마우스 숨김, 키보드 이동 가능)
        FInputModeGameOnly GameOnlyMode;
        SetInputMode(GameOnlyMode);
    }
}

✅ 핵심 요약

개념설명주의 사항
Title GameMode타이틀 전용 규칙DefaultPawnNone으로 설정할 것
OpenLevelIP 주소로 서버 접속스팀/콘솔 친구 초대는 Session 방식 사용
PostLogin접속 완료 이벤트GameMode에서 관리하며, 접속 직후 1회 실행됨
Input Mode입력 방식 결정레벨 이동 시 UIOnly \leftrightarrow GameOnly 전환 필수
profile
Shin Ji Yong // Unreal Engine 5 공부중입니다~

0개의 댓글