Make Unreal REAL.
article thumbnail
이득우의 언리얼 C++ 게임 개발의 정석

 

예제 폴더에서 UI_Menu 위젯 블루프린트를 프로젝트 폴더에 복사한다.

 

 

UI_Menu 위젯 블루프린트는 대략 다음과 같은 구성이다.

  • 배경 블러가 설정되어 있다.
  • Size Box를 통해 크기를 설정한다.
  • Vertical Box를 안에 배치해 스택처럼 하위 위젯들을 쌓는다.

 

디자이너의 Hierarchy에서 Is Variable이 체크되어 변수로 사용할 수 있는 하위 위젯은 굵은 글씨로 표시된다.

 

 

지금부터 해야할 것은 메뉴를 띄우기 위한 일시 정지 기능 구현과 각 버튼의 기능들을 구현해 바인딩하는 것이다.

  • btnResume: 게임으로 돌아가기
  • btnReturnToTitle: 타이틀 화면

 

Project Settings에서 M 키를 GamePause 액션에 매핑한다.

 

 

현재 이동, 회전, 공격, 점프, 뷰 전환 등 모든 입력 처리는 캐릭터 클래스에서 하고 있다.

  • 캐릭터가 플레이어 컨트롤러에 자신을 조종하는 방법을 제공하는 것이 효율적이기 때문이다.

 

단, 시스템에 관련된 입력 처리의 경우 플레이어 컨트롤러에 구현하면 빙의한 폰에 관계 없이 처리할 수 있으므로 플레이어 컨트롤러에 구현하는 것이 좋다.

  • APawn::DisableInput(APlayerController*) 함수의 경우, 플레이어 컨트롤러의 Input Stack에서 현재 폰을 제거한다.
  • 따라서 폰에 구현된 입력은 처리가 불가능하지만, 플레이어 컨트롤러에 구현된 입력 로직은 여전히 사용 가능하다.

 

 

OnGamePause() 함수는 GamePause 액션에 바인딩만 해 놓고 나중에 구현하도록 한다.

 

 

UI_Menu 위젯 블루프린트의 부모로 지정할 UserWidget을 상속 받은 클래스를 생성하고 UI_Menu 위젯 블루프린트의 부모 클래스로 지정한다.

 

 

CoreMinimal.h를 ArenaBattle.h로 변경한다.

 

 

UUserWidget::NativeConstruct() 함수는 UUserWidget::AddToViewport() 함수가 호출될 때, UI 생성이 완료된 후 위젯을 초기화하는 시점에 호출된다.

  • 이때 각 버튼의 이름으로 위젯을 찾고, 버튼이 존재하면 바인딩하는 로직을 구현한다.

 

 

헤더를 포함한다.

 

 

NativeConstruct() 함수에서 각 하위 위젯들을 가져와 변수에 저장한 후, OnClicked 델리게이트에 함수를 등록해 바인딩한다.

 

각 함수는 나중에 구현하도록 한다.

 

 

플레이어 컨트롤러로 돌아가서 UI_Menu 위젯 생성과 게임 정지 기능을 구현한다.

  1. 게임을 정지시킨다.
  2. 마우스 커서를 보이게 설정한다.
  3. UI 전용 입력 모드로 설정한다.

 

입력 모드를 변경하는 ChangeInputMode 함수와 입력 모드 변수를 선언한다.

 

UI_Menu 클래스를 저장할 클래스 변수와 위젯을 저장할 변수를 선언한다.

 

 

헤더를 포함한다.

 

 

생성자에서 UI_Menu 위젯 블루프린트 클래스를 가져온다.

  • 에셋 명 뒤에 _C를 붙이는 것을 잊지 말아야 한다.
  • 만약 에셋 경로에 가상 경로만 적었을 때 에셋을 찾지 못해 CDO를 생성하지 못했다는 오류가 발생하면, 아래처럼 에셋 종류를 추가해주면 해결된다.

 

 

BeginPlay() 함수에서 입력 모드 설정을 함수를 통하도록 변경해준다.

 

캐릭터의 스탯과 점수가 표시되는 HUD UI의 AddToViewport() 함수에 인자를 추가해 1의 ZOrder를 갖도록 한다.

  • 기본값은 0이며, 높을수록 앞에 배치된다.

 

 

APlayerController::SetInputMode() 함수에 입력 모드 변수를 전달하고 bShowMouseCursor 값을 변경해 게임 입력과 UI 입력을 설정한다.

  • 입력 모드에 특별히 설정할 것이 없다면, 변수를 만드는 대신 FInputModeGameOnly(), FInputModeUIOnly()와 같이 즉석에서 만들어 전달해도 된다.

 

 

이제 OnGamePause() 함수를 구현한다.

 

M 키가 눌리면 우선 위젯을 생성한다.

  • 여기서는 그때그때 새로 위젯을 생성하는데, 처음 한 번만 생성해도 무방하다.
  • RemoveFromParent() 함수를 호출해 뷰포트에서 제거했다고 하더라도, 포인터를 저장하고 있기 때문에 GC가 호출되지 않아 다시 AddToViewport() 함수를 호출할 수 있기 때문이다.

 

APlayerController::SetPause() 함수로 게임을 정지시킬 수 있다.

  • 플레이어만 멈추는 것이 아니라, 게임 전체가 멈춘다.
  • Tick, 타임라인, 애니메이션, 물리 등 시간과 연관된 것들이 멈추는 것이고 버튼 입력 등은 정상 작동한다.

 

UI 입력 모드로 설정한다.

 

 

플레이 도중 M 키를 누르면 메뉴 UI가 뜨고 게임이 멈추게 된다.

 

 

이제 위젯에서 <게임으로 돌아가기> 버튼과 <타이틀 화면> 버튼의 기능을 구현한다.

 

 

<게임으로 돌아가기> 버튼이 눌리면 위젯을 뷰포트에서 제거하고 입력 모드를 변경한 후 일시 정지를 해제한다.

  • UUserWidget::GetOwningPlayer() 함수를 통해 자신을 생성하고 관리하는 플레이어 컨트롤러를 가져올 수 있다.

 

 

<타이틀 화면> 버튼이 눌리면 Title 레벨을 새로 연다.

 

 

일시 정지 기능과 UI 제작에 성공했다.

 

profile

Make Unreal REAL.

@diesuki4

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그