기능 이해의 핵심은 게임의 일시정지 처리가 어떻게 일어나고, 왜 UI조작 등은 여전히 가능한가하는 부분입니다. Actor를 포함한 많은 객체들이 일시정지시에 틱을 멈추고 각종 액션을 처리하지 않도록 설계되어 있기 때문입니다. 이 설정은 객체마다 조정 가능한 옵션으로, 기본적으로 Widget과 PlayerController는 틱을 멈추지 않습니다. 하지만 한가지 유의할 점은, 각종 Input Action은 동작하지 않도록 막힙니다. 그래서 일시정지 상태에도 조작을 허용해줄 Action들에 대해서는 bTriggerWhenPaused를 true로 변경해주어야합니다. 그러면 PlayerController를 통해서 조작하고, UI는 업데이트 가능해지며, Actor를 포함한 각종 게임 플레이에 연관된 객체들은 멈추게 됩니다. 일시정지는 UGameplayStatics::SetGamePause를 호출하여 아주 쉽게 할 수 있습니다.
구현에서 신경쓴 부분은 UI 처리였습니다. 우리는 메뉴 버튼을 띄우거나, 일시정지 창을 띄우거나, 인벤토리 창을 열거나, 설정변경 창을 여는 경우 모두 게임이 멈추기를 원합니다. 그런데 이 UI들을 구현할때마다 모두 각자 Pause를 호출하는 것도 좋지 않고, 메뉴-설정같은 순서로 UI를 순서대로 열 수도 있습니다. 이 경우에 대한 처리를 일관되게 해 줄 수 있는 클래스가 필요했습니다. 그래서 UGameInstanceSubsystem를 상속한 클래스를 만들어서, World를 멈출 수 있는 위젯은 모두 여기서 만들고 없애도록 세팅했습니다. 새로운 위젯이 열릴 때마다 ZOrder를 1씩 올려서 기존의 UI에 가려지지 않도록 세팅했으며, 위젯이 열리거나 닫히는 순간에 일시정지 상태를 바꾸는 처리를 하도록 만들었습니다.
USaveGame을 상속한 클래스를 만들고, 이걸 저장하고 불러오는 기능을 만드는 중입니다. Save는 비동기로 진행되며, Load는 저장된 게임 데이터를 보여주는 UI를 띄우려면 어차피 데이터를 미리 읽어야하기 때문에, 동기로 진행됩니다. 핵심이 되는 함수는 3개입니다.
UGameplayStatics::AsyncSaveGameToSlot: 게임 저장(비동기)UGameplayStatics::LoadGameFromSlot: 게임 저장 정보 불러오기(동기)UGameplayStatics::DoesSaveGameExist : 게임 저장 정보가 있는지 확인별도로 저장할 정보가 없어 현재 레벨(umap), 플레이어의 위치와 각도만 저장하고 있습니다.
언리얼 엔진 세팅
F12)로 변경