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

 

예제 폴더에 있는 Resource > Chapter15 > Book > UI > UI_Select.uasset 파일과 Resource > Chapter15 > Maps > Select.umap 파일을 프로젝트 폴더에 복사한다.

 

 

플레이하면 화면 중앙에 캐릭터가 서 있는 모습을 볼 수 있다.

  • 3점 조명 기법은 아니지만, 비슷한 방식으로 캐릭터를 비춘다.

 

 

현재 Eye Adaptation (Auto Exposure) 기능이 활성화되어 있어 플레이를 시작한 후 서서히 캐릭터가 보이는 것을 볼 수 있다.

 

Post Process Volume을 배치해 Eye Adaption 기능을 끈다.

 

 

Min Brightness와 Max Brightness를 같은 값으로 설정한다.

 

Infinite Extent (Unbounds)에 체크해 범위를 월드 전체로 확장한다.

 

 

메인 타이틀 레벨에서 했던 방식과 비슷하게 ABUIPlayerController를 상속 받은 블루프린트 클래스를 생성한 후 띄울 위젯 클래스를 UI_Select로 지정한다.

 

 

이 레벨용 새로운 게임 모드를 생성하고 Player Controller Class와 Default Pawn Class를 설정해준다.

 

 

World Settings 패널에서 게임 모드를 설정해준다.

 

 

이제 플레이하면 캐릭터와 UI가 뜬다.

 

C++로 각 UI의 로직을 구현해본다.

 

 

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

 

 

CoreMinimal.h를 ArenaBattle.h로 변경해준다.

 

 

이전, 다음 버튼에 바인딩 할 NextCharacter() 함수를 선언하고 BP에서 사용할 수 있도록 BlueprintCallable 키워드를 지정한다.

  • 캐릭터를 나타내기 위해서는 현재 인덱스 번호와 최대 인덱스가 필요하다.

 

화면에 표시되는 Skeletal Mesh Actor의 Skeletal Mesh 컴포넌트를 가져와 저장할 약 스마트 포인터 타입의 변수도 선언한다.

  • TWeakPtr<T>는 UObject 형식에 사용할 수 없지만, TWeakObjectPtr<T> 형식은 사용할 수 있다.
  • 이 위젯과 Skeletal Mesh Actor의 소멸 시점이 다를 수 있기 때문에, 메모리 낭비를 줄이기 위해 약 포인터로 선언한다.

 

 

필요한 헤더를 포함한다.

 

 

NativeConstruct() 함수에서 ArenaBattleSetting 모듈의 ABCharacterSetting 클래스의 CDO를 가져와 최대 인덱스를 저장한다.

 

TActorIterator<T> It(UWorld*) 함수를 통해 월드에 배치된 T 타입(혹은 상속 받은)의 액터를 순회할 수 있는 반복자를 가져올 수 있다.

  • UGameplayStatics::GetAllActorsOfClass(UWorld*, T::StaticClass(), TArray<AActor*>&) 함수는 반복자가 아닌 액터 배열을 반환한다.
  • 현재 월드에는 1개의 Sekeletal Mesh Actor만 존재하므로, 해당 액터를 찾으면 Skeletal Mesh 컴포넌트를 가져와 저장하고 멈춘다.

 

참고로 Skeletal Mesh 에셋을 드래그해 월드에 배치하면 자동으로 Skeletal Mesh Actor가 된다.

 

 

bFoward 값에 따라 방향을 정하고 범위를 벗어나면 Repeat 시켜준다.

 

캐릭터 에셋의 FSoftObjectPath 타입의 가상 경로를 가져오고 이번에는 동기 방식으로 에셋을 로딩해 설정한다.

  • FStreamableManager::LoadSynchronous<T>(FSoftObjectPath) 함수를 통해 동기 에셋 로딩을 수행할 수 있다.
  • 캐릭터를 둘러보는 것 외에는 월드에서 하는 것이 없고 에셋 로딩 시간이 그리 길지 않기 때문에 동기 로딩을 해도 된다.

 

 

버튼에 동작을 바인딩하기 전에 해야할 것이 있다.

 

이 레벨에서 선택한 캐릭터를 Gameplay 레벨로 전달하기 위해서는 게임 데이터에 캐릭터 인덱스 번호도 함께 저장하고 관리해줘야 한다.

 

 

플레이어 스테이트에서 캐릭터 인덱스를 제공한다.

 

 

캐릭터의 BeginPlay() 함수에서 4번 캐릭터로 고정되어 있던 플레이어 캐릭터를 플레이어 스테이트에 저장된 게임 데이터의 캐릭터로 변경해준다.

 

 

이제 다시 돌아와 UI를 바인딩해 준다.

 

현재 NextCharacter() 함수는 BlueprintCallable 키워드가 지정되어 BP에서도 사용할 수 있기 때문에 UI에 바인딩하는 아래 내용들은 BP에서도 수행할 수 있다.

 

이전/다음 버튼, 텍스트 상자, 확인 버튼을 저장할 변수와 OnClicked 델리게이트에 등록할 함수들을 선언한다.

 

 

필요한 헤더를 포함한다

 

 

AddToViewport() 시에 UI 생성이 끝난 후 위젯을 초기화하는 시점에 호출되는 NativeConstruct() 함수에서 각 하위 위젯을 가져오고 OnClicked 델리게이트에 함수들을 등록한다.

  • OnClicked는 BP에서 사용할 수 있는 다이나믹 멀티캐스트 델리게이트이다.

 

 

이전, 다음 버튼의 동작이다.

 

 

확인 버튼의 동작이다.

 

덱스트 상자의 문자열은 UEditableText::GetText().ToString() 함수를 통해 FString 타입으로 가져올 수 있다.

 

이 레벨은 <새로 시작하기> 시에 등장하는 레벨이므로 새로운 게임 데이터를 생성해 저장해준 후 바로 Gameplay 레벨로 이동한다.

  • UGameplayStatics::OpenLevel(UWorld, FText) 함수를 이용해 레벨 이름으로 새로운 레벨을 열 수 있다.

 

 

Title, Select, Gameplay 레벨이 모두 완성되었으므로 시작 레벨을 Title로 변경해준다.

 

 

플레이 후 <새로 시작하기> 버튼을 클릭하면 캐릭터 선택 레벨로 이동한다.

 

 

캐릭터 선택 레벨을 만들고 선택 정보를 다음 레벨에 전달하는 데 성공했다.

 

profile

Make Unreal REAL.

@diesuki4

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

검색 태그