저장 및 로드 기본 구현
게임 개발에서 데이터 저장(Save) 과 로드(Load) 기능은 필수적입니다. 플레이어가 게임을 껐다가 다시 켰을 때, 이전에 진행했던 상태를 그대로 이어서 플레이할 수 있어야 하기 때문이죠. 단순히 점수나 설정뿐만 아니라, 플레이어의 위치, 인벤토리, 퀘스트 진행도, 월드 상태 등 다양한 데이터를 저장하고 불러올 수 있어야 합니다.
언리얼 엔진은 이러한 저장 및 로드 기능을 쉽게 구현할 수 있도록 저장 게임 오브젝트(Save Game Object) 시스템을 제공합니다.
저장 게임 오브젝트란 무엇인가?
저장 게임 오브젝트(Save Game Object) 는 게임에 저장하고 싶은 모든 데이터를 담는 특별한 종류의 오브젝트입니다. 이 오브젝트는 게임이 종료되거나 레벨이 변경되어도 파괴되지 않고, 마치 파일처럼 디스크에 저장(직렬화)되었다가 필요할 때 다시 메모리로 로드(역직렬화)될 수 있습니다.
저장 게임 오브젝트는 다음과 같은 특징을 가집니다.
- 영속성(Persistence): 게임 세션이 끝나도 데이터가 유지됩니다.
- 사용자 정의 가능: 개발자가 저장하고 싶은 데이터(변수)를 직접 정의할 수 있습니다.
- 블루프린트 접근성: 블루프린트에서 쉽게 생성하고 데이터를 읽고 쓸 수 있습니다.
- 플랫폼 독립성: 내부적으로 파일 시스템을 다루는 복잡한 과정을 언리얼 엔진이 처리해주므로, 개발자는 저장/로드 로직에만 집중할 수 있습니다.
저장 게임 오브젝트 생성 및 정의
가장 먼저 할 일은 어떤 데이터를 저장할지 정의하는 것입니다. 이는 저장 게임 오브젝트 블루프린트를 생성하여 그 안에 저장할 변수들을 정의하는 방식으로 이루어집니다.
- 저장 게임 블루프린트 생성
- 콘텐츠 브라우저에서 마우스 오른쪽 버튼을 클릭합니다.
블루프린트 클래스(Blueprint Class)
를 선택합니다.모든 클래스(All Classes)
를 펼친 후SaveGame
을 검색하여 선택합니다.- 이름을 지정합니다. (예:
BP_MySaveGame
- 일반적으로 'BP_' 접두사를 사용합니다.)
- 저장할 변수 추가
- 생성된
BP_MySaveGame
블루프린트 에디터를 엽니다. - 변수 패널에서 저장하고 싶은 데이터를 나타내는 변수들을 추가합니다.
- 예시
PlayerScore
(Integer)PlayerLocation
(Vector)UnlockedLevels
(Array of Integer)PlayerName
(Text)
- 예시
- 컴파일하고 저장합니다.
- 생성된
이제 BP_MySaveGame
은 게임 상태를 담을 수 있는 '데이터 컨테이너'가 되었습니다.
데이터 저장(Save) 기본 구현
데이터 저장 과정은 주로 플레이어의 입력(예: S
키), 특정 이벤트(예: 체크포인트 도달, 레벨 전환), 또는 게임 종료 시점에 이루어집니다.
- 저장 로직을 구현할 블루프린트 열기: (예:
BP_PlayerCharacter
또는BP_GameManager
) Create SaveGame Object
노드Event S
키 입력(저장 버튼) 노드 뒤에Create SaveGame Object
노드를 추가합니다.Save Game Class
핀에 여러분이 만든BP_MySaveGame
을 지정합니다.- 이 노드는 새로운
BP_MySaveGame
인스턴스를 메모리에 생성하여 반환합니다.
- 데이터 채우기 (캐스팅 후 변수 설정)
Create SaveGame Object
의Return Value
출력 핀에서 드래그하여Cast To BP_MySaveGame
노드를 연결합니다. (생성된 오브젝트를 실제 클래스 타입으로 캐스팅하여 접근하기 위함입니다.)Cast To BP_MySaveGame
의As BP My Save Game
출력 핀에서 드래그하여Set PlayerScore
(또는 여러분이 정의한 다른 변수)와 같은 노드를 추가합니다.- 현재 게임 상태에서 가져온 값들(예:
Get PlayerScore
(Game Instance에서 가져온),Get ActorLocation
등)을 저장 게임 오브젝트의 변수들에 연결합니다.
Save Game to Slot
노드- 데이터를 모두 채운 후,
Set
노드의 실행 핀 뒤에Save Game to Slot
노드를 추가합니다. SaveGame Object
핀에는Cast To BP_MySaveGame
의As BP My Save Game
출력 핀을 연결합니다.Slot Name
핀에는 저장할 파일의 고유한 이름을Text
형태로 입력합니다. (예:"SaveSlot1"
) 이 이름은 게임 내에서 저장 파일을 구분하는 데 사용됩니다.User Index
핀은 주로 멀티플레이어 게임에서 여러 사용자의 저장을 구분할 때 사용됩니다. 싱글 플레이어 게임에서는 보통0
을 사용합니다.Return Value
(불리언)는 저장이 성공했는지 여부를 반환합니다.
- 데이터를 모두 채운 후,
데이터 로드(Load) 기본 구현
데이터 로드 과정은 주로 게임 시작 시(예: Event BeginPlay
에서 로드 확인), 또는 메인 메뉴에서 '이어하기' 버튼을 눌렀을 때 이루어집니다.
- 로드 로직을 구현할 블루프린트 열기: (예:
BP_PlayerCharacter
또는BP_GameManager
) Does SaveGame Exist
노드 (선택 사항, 안정성)- 로드를 시도하기 전에, 먼저 해당 슬롯 이름으로 저장된 파일이 존재하는지 확인하는 것이 좋습니다.
Event BeginPlay
(또는 '로드' 버튼 클릭 이벤트) 뒤에Does SaveGame Exist
노드를 추가합니다.Slot Name
과User Index
를 저장 시 사용했던 것과 동일하게 입력합니다.- 이 노드의
Return Value
를Branch
노드의Condition
에 연결합니다.True
(저장 파일 존재): 로드 로직으로 진행합니다.False
(저장 파일 없음): 새 게임 시작 로직으로 진행하거나, 로드 실패 메시지를 출력합니다.
Load Game From Slot
노드Branch
노드의True
실행 핀 뒤에Load Game From Slot
노드를 추가합니다.Slot Name
과User Index
를 저장 시 사용했던 것과 동일하게 입력합니다.- 이 노드는 저장된 파일이 있다면
BP_MySaveGame
인스턴스를 메모리로 로드하여 반환합니다.
- 로드된 데이터 활용 (캐스팅 후 변수 가져오기)
Load Game From Slot
의Return Value
출력 핀에서 드래그하여Cast To BP_MySaveGame
노드를 연결합니다.Cast To BP_MySaveGame
의As BP My Save Game
출력 핀에서 드래그하여Get PlayerScore
,Get PlayerLocation
등 저장했던 변수들을 가져옵니다.- 가져온 값들을 현재 게임 오브젝트의 변수(예:
Set PlayerScore
(Game Instance의),Set ActorLocation
)에 연결하여 게임 상태를 복원합니다. - 예시:
Set ActorLocation
노드를 연결하여 플레이어의 위치를 로드된PlayerLocation
으로 설정합니다.
주의사항 및 고급 활용
- 저장할 데이터만 SaveGame Object에: 저장 게임 오브젝트에는 정말로 '저장'해야 할 데이터만 포함해야 합니다. 임시적인 데이터나 게임 내에서 실시간으로 계산되는 데이터는 포함하지 않는 것이 좋습니다.
- 비동기 저장/로드: 대용량 데이터를 저장하거나 로드할 때 게임이 잠깐 멈추는 현상(프레임 드롭)이 발생할 수 있습니다. 이를 방지하기 위해
Async Save Game to Slot
또는Async Load Game from Slot
과 같은 비동기 노드를 사용할 수 있습니다. 이는 백그라운드에서 작업을 처리하므로 게임이 멈추지 않습니다. - 슬롯 이름 관리: 여러 개의 저장 파일을 지원하려면 각 저장 파일마다 고유한
Slot Name
을 사용해야 합니다. - 유효성 검사:
Cast
노드 사용 시IsValid
핀을 활용하여 성공적으로 캐스팅되었는지,Access None
오류가 발생하지 않도록 항상 확인하는 습관을 들이는 것이 좋습니다. - 버전 관리: 게임 업데이트 시 저장 게임 오브젝트의 구조가 변경될 수 있습니다. 이때 이전 버전의 저장 파일을 불러올 때 문제가 발생할 수 있으므로, 저장 게임 오브젝트에 버전 변수를 추가하여 호환성을 관리하는 고급 기법도 고려해야 합니다.
저장 및 로드 기능은 게임의 핵심적인 부분이며, 이 저장 게임 오브젝트 시스템을 통해 비교적 쉽게 구현할 수 있습니다. 복잡한 게임에서는 저장해야 할 데이터가 많아지므로, 데이터를 어떻게 구조화하고 어떤 시점에 저장/로드할지 신중하게 설계하는 것이 중요합니다.
이번 절에서는 언리얼 엔진의 저장 게임 오브젝트를 활용한 데이터 저장 및 로드의 기본 구현 방법에 대해 알아보았습니다. 이 기능은 플레이어의 진행 상황을 유지하고 몰입감을 높이는 데 필수적입니다.