본문 바로가기

게임 인스턴스 활용 데이터 공유

레벨 전환에도 유지되는 GameInstance를 설정하고 여러 레벨과 블루프린트가 공유할 데이터를 관리합니다.

지금까지는 액터 블루프린트 간 직접 통신 방법을 살펴봤습니다.

하지만 플레이어 점수, 잠금 해제 아이템, 게임 설정처럼 레벨 변경 이후에도 유지되어야 하는 데이터는 별도 관리가 필요합니다.

이런 데이터를 효율적으로 관리하기 위해 언리얼 엔진은 게임 인스턴스(Game Instance)를 제공합니다.

이번 절에서는 게임 인스턴스의 기본 개념과 데이터 공유 방법을 정리합니다.


게임 인스턴스란 무엇인가?

게임 인스턴스(Game Instance)는 하나의 실행 중인 게임 인스턴스 안에서 시작부터 종료까지 유지되는 오브젝트입니다.

일반적인 레벨 전환에도 같은 GameInstance를 사용합니다. 여러 PIE 게임 인스턴스를 실행하면 각각 따로 생성되며, 서버와 클라이언트가 하나를 공유하거나 그 변수가 자동 복제되는 것은 아닙니다.

다른 주요 클래스들(예: Game Mode, Player Controller, HUD 등)은 레벨이 변경될 때마다 새로 생성되거나 파괴될 수 있지만, 게임 인스턴스는 그렇지 않습니다.

이러한 특성 때문에 게임 인스턴스는 다음과 같은 용도로 사용하기에 가장 적합합니다.

  • 게임 세션 전반에 걸쳐 유지되어야 하는 데이터 저장: 플레이어 점수, 인벤토리, 잠금 해제 상태, 게임 설정 등.
  • 레벨 간 데이터 전달: 특정 레벨에서 얻은 정보를 다음 레벨로 전달해야 할 때.
  • 글로벌 이벤트 디스패처: 게임 전체에 영향을 미치는 이벤트를 알릴 때.

커스텀 게임 인스턴스 생성 및 설정

기본적으로 언리얼 엔진은 UGameInstance라는 기본 게임 인스턴스 클래스를 사용합니다.

우리가 이 기능을 활용하려면 이 클래스를 상속받는 커스텀 게임 인스턴스 블루프린트를 생성하고, 프로젝트 설정에서 이를 사용하도록 지정해야 합니다.

커스텀 게임 인스턴스 블루프린트 생성
  • 콘텐츠 브라우저에서 마우스 오른쪽 버튼 클릭 > 블루프린트 클래스(Blueprint Class) 선택.
  • 모든 클래스(All Classes)를 펼친 후 GameInstance를 검색하여 선택합니다.
  • 이름을 지정합니다. (예: BP_MyGameInstance - 일반적으로 BP_ 접두사를 사용합니다.)
프로젝트 설정에서 게임 인스턴스 지정
  • 언리얼 에디터 상단 메뉴에서 편집(Edit) > 프로젝트 세팅(Project Settings)을 클릭합니다.
  • 좌측 패널에서 맵 & 모드(Maps & Modes) 섹션으로 이동합니다.
  • Game Instance 드롭다운 메뉴에서 여러분이 생성한 BP_MyGameInstance를 선택합니다.
  • 이제 게임이 시작될 때마다 BP_MyGameInstance의 인스턴스가 생성되어 사용될 것입니다.

게임 인스턴스를 통한 데이터 공유 예시

이제 BP_MyGameInstance에 데이터를 저장하고 다른 블루프린트에서 이 데이터에 접근하는 방법을 알아보겠습니다.

예시: 플레이어 점수 공유
게임 인스턴스에 변수 추가
  • BP_MyGameInstance 블루프린트 에디터를 엽니다.
  • 변수 패널에서 새 변수를 추가합니다.
  • 이름을 PlayerScore로 지정하고, 변수 타입을 Integer로 설정합니다.
  • 컴파일하고 저장합니다.
플레이어 캐릭터에서 점수 증가 및 저장
  • BP_PlayerCharacter 블루프린트를 엽니다.
  • Get Game Instance 노드를 추가하고, Event BeginPlay의 실행 선은 뒤에서 만들 캐스트 노드에 연결합니다. Get Game Instance는 값을 제공하는 노드입니다.
  • Get Game Instance의 출력 핀에서 드래그하여 Cast To BP_MyGameInstance 노드를 연결합니다. 캐스트 성공 실행 핀에서만 다음 할당을 수행하고 Cast Failed에서는 프로젝트의 Game Instance Class 설정을 확인합니다. IsValid는 참조의 유효성을 검사하며 캐스트 성공 여부를 대신 판정하지 않습니다.
  • Cast To BP_MyGameInstance의 As BP My Game Instance 출력 핀을 변수로 승격시켜 저장해 두면 편리합니다. (예: MyGameInstanceRef)
  • 이제 플레이어가 적을 처치하거나 아이템을 획득했을 때 점수를 증가시키는 로직을 만듭니다. 예를 들어, F 키를 누를 때마다 점수가 10점씩 증가하도록 해 봅시다.
    • Event F 키 입력 노드를 추가합니다.
    • MyGameInstanceRef 변수(Get 노드)에서 드래그하여 Get PlayerScore 노드를 가져옵니다.
    • Get PlayerScore의 출력값을 + 연산자로 10과 더합니다.
    • MyGameInstanceRef 변수(Get 노드)에서 드래그하여 Set PlayerScore 노드를 가져와 + 연산 결과값을 연결합니다.
    • 입력 이벤트에서 실행 분기가 있는 IsValid로 MyGameInstanceRef를 확인한 뒤, 유효한 분기를 Set PlayerScore → Print String으로 연결합니다. 출력값은 갱신한 PlayerScore를 다시 읽어 연결합니다.
다른 레벨에서 점수 불러오기
  • 새로운 레벨(예: Level_2)을 생성하고 저장합니다.
  • Level_2에서도 입력을 받는 BP_PlayerCharacter를 사용합니다. GameMode의 기본 Pawn으로 스폰시키거나, 직접 배치했다면 Possess/Auto Possess 설정을 맞춥니다. 두 방식을 겹쳐 불필요한 캐릭터를 중복 생성하지 않습니다.
  • 같은 BP_PlayerCharacter 클래스에는 앞에서 만든 초기화 그래프가 이미 있으므로, 새 인스턴스의 BeginPlay에서 이를 다시 실행해 MyGameInstanceRef를 얻습니다.
  • MyGameInstanceRef에서 Get PlayerScore를 호출하여 Print String으로 점수를 출력하도록 합니다.
  • 메인 레벨에서 F 키를 눌러 점수를 올린 후, 다른 레벨로 이동하는 로직을 추가합니다. (예: Open Level (by Name) 노드 사용)
  • 게임을 플레이하며 점수를 올린 후, 레벨을 변경하면 변경된 레벨에서도 이전 점수가 그대로 유지되어 출력되는 것을 확인할 수 있습니다.

레벨 전환 데이터는 어디에 보관해야 하는지를 먼저 나누면 설계가 단순해집니다.

레벨 이동과 새 실행을 비교하기

GameInstance의 PlayerScore 기본값은 0입니다. Level_1에서 F 입력을 세 번 처리해 매번 10을 더한 뒤, 같은 실행에서 Level_2로 Open Level합니다. Level_2의 BeginPlay는 참조를 얻어 읽기만 하며 점수를 초기화하지 않습니다. 첫 출력은 얼마일까요? SaveGame 처리가 전혀 없는 상태에서 Stop 후 새 Play를 시작해도 그 값이 남을까요?

메모리 값을 유지하는 범위

같은 실행의 Level_2에서는 0 + 10 + 10 + 10 = 30을 읽습니다. 새 Play에서는 새 GameInstance를 만들므로 이 조건에서는 기본값 0부터 시작합니다. 모든 레벨의 BeginPlay에서 점수를 0으로 Set하면 같은 GameInstance라도 직접 덮어쓰는 것이므로, 레벨 이동의 보존 기능과 초기화 로직을 함께 점검해야 합니다. 실행 종료 이후에도 값을 보존하려면 별도의 저장·불러오기 기능이 필요합니다.

레벨 전환 중 점수 보관

Level1에서 같은 GameInstance 점수를 갱신하고 레벨 전환 후 새 캐릭터가 30을 읽는 실제 세션 상태이다. 새 Play는 별도 인스턴스의 초깃값 0에서 시작하며 저장 파일의 영속성으로 확대하지 않는다.

ONE RUN · TWO LEVELS · SHARED VALUE

같은 실행의 GameInstance에서 다음 레벨이 값을 읽습니다

Level_1의 캐릭터는 GameInstance 메모리의 PlayerScore를 갱신합니다. 일반적인 레벨 전환 후 Level_2의 새 캐릭터는 같은 GameInstance 참조를 다시 얻어 값을 읽습니다.

같은 게임 실행 안에서 레벨 사이에 점수 전달Level_1 캐릭터가 GameInstance의 PlayerScore를 갱신하고, Level_2의 새 캐릭터가 같은 GameInstance에서 값을 읽습니다.Level_1 캐릭터점수 변경GameInstancePlayerScoreLevel_2 캐릭터점수 읽기메모리 갱신조회값
같은 게임 실행 안에서 레벨 사이에 점수 전달Level_1 캐릭터가 GameInstance의 PlayerScore를 갱신하고, Level_2의 새 캐릭터가 같은 GameInstance에서 값을 읽습니다. 같은 실행의 공유값 흐름이며 캐릭터 참조를 다음 레벨에 넘기는 관계가 아닙니다.
Level_1 캐릭터점수 변경
메모리 갱신메모리 갱신Level_1 캐릭터 · 점수 변경 → GameInstance · PlayerScore
GameInstancePlayerScore
조회값조회값GameInstance · PlayerScore → Level_2 캐릭터 · 점수 읽기
Level_2 캐릭터점수 읽기

일반적인 레벨 전환 예시입니다. 캐릭터 참조를 넘기는 것이 아니라 같은 GameInstance의 값을 새 캐릭터가 읽습니다.

메모리 보관과 디스크 저장의 경계

실행 종료 후에도 값을 남기려면 SaveGame 등으로 명시적으로 저장하고 불러옵니다. 각 PIE 게임 인스턴스는 별도의 GameInstance를 사용하며 서버·클라이언트 간 자동 공유도 아닙니다.

이 예의 조건

  • 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
  • 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
Level1 기록

같은 GameInstance에 점수를 저장한다.

  • 점수: 30
  • 원천: 현재 세션 GameInstance
  • 레벨 로컬 캐릭터 값과 세션 소유 값을 구분한다.
레벨 전환

Level1 캐릭터가 끝나고 새 캐릭터가 준비된다.

  • GameInstance: 같은 인스턴스 유지
  • 캐릭터: 교체
  • 레벨 전환은 새 Play 세션 생성과 다르다.
새 캐릭터 읽기

새 레벨 캐릭터가 30을 읽는다.

  • 조회: 30
  • 새 Play의 별도 값: 0
  • 이 유지 기능을 디스크 저장 파일 영속성으로 확대하지 않는다.

레벨 전환 중 점수 보관

Level1에서 같은 GameInstance 점수를 갱신하고 레벨 전환 후 새 캐릭터가 30을 읽는 실제 세션 상태이다. 새 Play는 별도 인스턴스의 초깃값 0에서 시작하며 저장 파일의 영속성으로 확대하지 않는다.

ONE RUN · TWO LEVELS · SHARED VALUE

같은 실행의 GameInstance에서 다음 레벨이 값을 읽습니다

Level_1의 캐릭터는 GameInstance 메모리의 PlayerScore를 갱신합니다. 일반적인 레벨 전환 후 Level_2의 새 캐릭터는 같은 GameInstance 참조를 다시 얻어 값을 읽습니다.

같은 게임 실행 안에서 레벨 사이에 점수 전달Level_1 캐릭터가 GameInstance의 PlayerScore를 갱신하고, Level_2의 새 캐릭터가 같은 GameInstance에서 값을 읽습니다.Level_1 캐릭터점수 변경GameInstancePlayerScoreLevel_2 캐릭터점수 읽기메모리 갱신조회값
같은 게임 실행 안에서 레벨 사이에 점수 전달Level_1 캐릭터가 GameInstance의 PlayerScore를 갱신하고, Level_2의 새 캐릭터가 같은 GameInstance에서 값을 읽습니다. 같은 실행의 공유값 흐름이며 캐릭터 참조를 다음 레벨에 넘기는 관계가 아닙니다.
Level_1 캐릭터점수 변경
메모리 갱신메모리 갱신Level_1 캐릭터 · 점수 변경 → GameInstance · PlayerScore
GameInstancePlayerScore
조회값조회값GameInstance · PlayerScore → Level_2 캐릭터 · 점수 읽기
Level_2 캐릭터점수 읽기

일반적인 레벨 전환 예시입니다. 캐릭터 참조를 넘기는 것이 아니라 같은 GameInstance의 값을 새 캐릭터가 읽습니다.

메모리 보관과 디스크 저장의 경계

실행 종료 후에도 값을 남기려면 SaveGame 등으로 명시적으로 저장하고 불러옵니다. 각 PIE 게임 인스턴스는 별도의 GameInstance를 사용하며 서버·클라이언트 간 자동 공유도 아닙니다.

이 예의 조건

  • 본문과 원 도표에 제시된 사례의 입력·조건을 사용합니다. 설명용 수치나 독립 비교 경로는 각 단계에 표시합니다.
  • 현재 상태·값과 전환 근거의 위치는 모든 단계에서 같습니다. 조건이 맞지 않거나 실행되지 않은 경로를 성공한 동작으로 해석하지 않습니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
Level1 기록

같은 GameInstance에 점수를 저장한다.

  • 점수: 30
  • 원천: 현재 세션 GameInstance
  • 레벨 로컬 캐릭터 값과 세션 소유 값을 구분한다.
레벨 전환

Level1 캐릭터가 끝나고 새 캐릭터가 준비된다.

  • GameInstance: 같은 인스턴스 유지
  • 캐릭터: 교체
  • 레벨 전환은 새 Play 세션 생성과 다르다.
새 캐릭터 읽기

새 레벨 캐릭터가 30을 읽는다.

  • 조회: 30
  • 새 Play의 별도 값: 0
  • 이 유지 기능을 디스크 저장 파일 영속성으로 확대하지 않는다.

게임 인스턴스 활용 시 고려사항

  • 저장 범위: 앱 종료 후 다시 실행할 때도 값이 필요하면 SaveGame 등을 사용해 명시적으로 디스크에 저장하고 불러와야 합니다. GameInstance의 메모리 변수만으로는 지속되지 않습니다.
  • 글로벌 접근성: 유효한 World Context를 제공하는 액터 등의 블루프린트에서 Get Game Instance로 접근합니다. 임의의 모든 UObject에 같은 접근 문맥이 있는 것은 아닙니다. 이는 게임 전반에 걸쳐 공유되어야 하는 데이터에 대한 중앙 집중식 접근점을 제공합니다.
  • 과도한 사용 지양: 게임 인스턴스는 매우 강력한 도구이지만, 모든 데이터를 게임 인스턴스에 저장하는 것은 좋지 않습니다. 특정 레벨에만 필요한 데이터나, 특정 액터에만 국한된 데이터는 해당 레벨이나 액터 내부에 관리하는 것이 더 효율적입니다. 게임 인스턴스는 정말로 게임 세션 전반에 걸쳐 유지되어야 하는 '글로벌' 데이터에만 사용하는 것이 좋습니다.
  • 초기화와 정리: 블루프린트의 Event Init와 Event Shutdown에서 GameInstance의 초기화·종료 처리를 구성합니다. C++의 OnStart를 일반적인 블루프린트 Event Start와 혼동하지 않습니다. 월드 액터 준비가 필요한 로직은 해당 월드의 플레이 시점에 수행합니다.
  • 월드 액터 참조: GameInstance에 참조를 보관해도 액터의 Destroy나 레벨 언로드를 막지는 못합니다. 다음 레벨에 전달할 값이나 식별자를 보관하고 새 월드에서 필요한 액터를 다시 찾습니다.

게임 인스턴스는 언리얼 엔진에서 게임의 상태를 관리하고 레벨 간에 데이터를 원활하게 공유하는 데 필수적인 개념입니다.

이를 통해 더욱 견고하고 확장 가능한 게임 시스템을 구축할 수 있습니다.


이번 절에서는 게임 인스턴스의 개념과 이를 활용한 데이터 공유 방법에 대해 알아보았습니다.