[UE5] GameInstance Basics: Carrying Score Across Three Stages

Created: 2026-07-20Last updated: 2026-09-07

Carry score and clear records across level changes with UE5's GameInstance. Covers creating and registering the class, Get Game Instance and Cast, preventing double counting, and resetting for a new run, through a three-stage Blueprint hands-on.

You collect 30 coins on stage 1 and move to the next stage. But the on-screen count is back to 0. You put it in a player variable, so why did it not survive?

Opening another level with Open Level rebuilds the original character and placed Actors. To keep a variable's value, you need somewhere that outlives that Actor.

That is what GameInstance is for. It stays the same across level changes during this run of the game. In this article we add up scores across three stages and carry the total and clear count into a final screen.

In other engines : this is a management object with DontDestroyOnLoad in Unity, or Godot's Autoload (singleton) . It is not "one per project" though; it is one per running game .

The GameInstance score continuing across stage changes

What You'll Learn

  • Creating your own GameInstance and registering it for the project
  • Updating the record from another Actor and reading it in the next level
  • Preventing the same stage from scoring twice
  • Separating revisiting with the record kept from starting a new run

This is for people who can create Blueprint variables and functions. We use single-player in the Third Person template and switch whole levels with Open Level .

Sponsored

GameInstance is memory for this play session

GameInstance is an object UE creates when the game starts and uses until the game ends. It is not placed in a level like an Actor and has no position or appearance.

Level switching here has these differences.

Where it livesWhen the next level opens
Variables on characters and placed ActorsThe original Actors are destroyed and new ones start from defaults
Variables on GameMode or Level BlueprintThey switch to the newly opened level's
Variables on GameInstanceThe same GameInstance remains with its values intact
GameInstance persists across three levels while each level's Actors are replaced

Thinking of it as "the record you deposited outside the character survives", not "the character survives" makes the use case clear. The new level's display side reads that record.

That said, stopping Play and starting again gives you a new GameInstance too. In a shipped build, the boundary is closing the application. Returning to the title screen alone does not erase the values.

GameInstance is not the only way to carry things over, but it is an accessible entry point for cross-level numbers in Blueprint. The level transition article connects to this usage too.

Create it and register it with the project

1. Create a Blueprint with GameInstance as its parent

Right-click in the Content Browser and choose "Blueprint Class". Search "All Classes" for GameInstance and create BP_GameInstance .

Open it and add these two variables. Compile, then check the defaults.

Variable nameTypeDefault and purpose
TotalScoreInteger0. This run's total
ClearedStagesArray of NameEmpty. The IDs of stages cleared this run

Name handles identifiers such as Stage01 . Making it an Array holds a list of same-typed values. ClearedStages records Stage01, Stage02, and Stage03 in the order you pass them.

2. Set the project to use this class

Open "Edit → Project Settings → Maps & Modes" and set "Game Instance Class" to BP_GameInstance .

Creating the GameInstance, adding variables, and registering it as the Game Instance Class

Creating the class does not put it in use. Only after registering it here does UE create your BP_GameInstance. After changing the setting, stop Play and start again.

Update the score and clear record

The entry point for fetching the GameInstance is Get Game Instance . It returns a reference to the GameInstance in use. A reference says "which object to use"; it is not logic creating a new one each call.

Passing that output to Cast To BP_GameInstance 's Object gives you access to your own variables and functions. The Cast confirms the fetched target can be treated as a BP_GameInstance. We build the actual wiring later on the goal and status Actors.

First, prepare two functions inside BP_GameInstance: "display" and "record a clear".

1. ShowSummary displays the current record

Create ShowSummary under BP_GameInstance's "Functions". Add no inputs or outputs and leave Pure disabled. It prints text, so it is a function called with white exec.

Place Format Text and enter this into Format.

Total: {Total} / Cleared: {Cleared}

Connect a Get of TotalScore to Total. Create Length from a Get of ClearedStages and connect its output to Cleared. Length is the array's item count, so three recorded stages give 3. If a number-to-Text conversion node is inserted automatically, leave it.

Feeding TotalScore and ClearedStages' Length into Format Text

Wire white exec from the function entry to Print Text and pass Format Text's Result to In Text. Enable Print to Screen and Print to Log with Duration 10 and Key RunSummary.

Passing ShowSummary's exec wire and the text from Format Text to Print Text

Now you can print the record at the moment you call it, to screen and the Output Log. Using the same Key updates the on-screen display.

2. ClearStage adds score only on a first clear

Create a function ClearStage on the same BP_GameInstance with two inputs.

Input nameTypeExample value
StageIDNameStage01
ScoreInteger120

Our rule is "each stage's score counts once per run" . Replaying and passing the same goal does not increase the total.

Create Contains Item from a Get of ClearedStages, passing the StageID input to Item to Find. Contains Item returns true or false for "is this ID in the list".

Wire white exec from the function entry to a Branch with Contains Item's Return Value into Condition. On True, Print Text This stage is already recorded and end. Only on False continue to the recording logic.

Checking whether the clear list contains StageID and continuing to recording only on a first clear

From False, wire white exec in this order.

  1. Add Unique : Target Array = a Get of ClearedStages, New Item = the StageID input
  2. Set TotalScore : the value is "Get TotalScore + the Score input", using integer +
  3. ShowSummary : Target is Self
Adding the uncleared ID and adding this Score to the current total

Add Unique adds without duplicating an existing ID in the array. That alone does not stop the score addition after it. Branching on Contains Item first protects both the list and the score from double updates. We do not use Add Unique's Return Value here.

Other Print Texts in this article, such as the already-recorded message, use Duration 5, Key None, with screen and log both enabled. Compile and save BP_GameInstance so other Blueprints can call its functions.

Sponsored

Hands-On: record at three goals and advance

1. Prepare four levels

In a Third Person Blueprint project, create levels from "File → New Level → Basic" and save them under Content/Maps with these names.

  • L_Stage01
  • L_Stage02
  • L_Stage03
  • L_Result

Give each level a walkable floor and a Player Start, and set "World Settings" → "GameMode Override" to BP_ThirdPersonGameMode . Play and confirm the character spawns and walks. In versions offering a template Variant, use None.

2. Create the goal Actor

Create BP_StageGoal with Actor as its parent. Add a Box Collision as a child of DefaultSceneRoot named Trigger with Relative Location (0,0,100) and Box Extent (100,100,100) .

Set Trigger's Collision Presets to Custom, Collision Enabled to Query Only, and Object Type to WorldDynamic. Overlap for Pawn only, Ignore for the rest, with Generate Overlap Events enabled.

Overlap detects entering a region without pushing back like a wall. On BP_ThirdPersonCharacter, enable the Capsule Component's Generate Overlap Events and disable the Mesh's, so detection uses the capsule.

Add a Static Mesh with a Cube as a visible marker. Name it Marker with Relative Location (0,-120,60) , Scale (0.15,0.15,1.2) , and Collision NoCollision.

The goal layout with the character passing a Trigger beside a pillar

Create these variables on BP_StageGoal.

Variable nameTypeDefaultInstance Editable
StageIDNameNoneEnabled
StageScoreInteger0Enabled
NextLevelNameNoneEnabled
IsTransitioningBooleanfalseDisabled

Enabling Instance Editable lets each placed instance have different values. Place one BP_StageGoal in each stage and set the following. L_Result gets no goal.

Where placedStageIDStageScoreNextLevel
L_Stage01Stage01120/Game/Maps/L_Stage02
L_Stage02Stage0280/Game/Maps/L_Stage03
L_Stage03Stage03150/Game/Maps/L_Result

NextLevel is the Name of the level to open next. To avoid name collisions we use paths with Content replaced by /Game . Do not append .umap .

Place goals away from the Player Start. With the floor at Z=0, for instance, putting the goal Actor at (500,0,0) and the Player Start at (0,0,100) lets you walk up to it.

3. React only when the player touches it

Select Trigger in BP_StageGoal and add On Component Begin Overlap. Wire the white output to Cast To BP_ThirdPersonCharacter with Other Actor into Object. Other Actor is whatever just entered the region.

From the Cast's success, go to a Branch with a Get of IsTransitioning into Condition. Leave True unconnected and, from False, go to Set IsTransitioning = true.

Checking the Overlap target and starting the logic only if a transition is not already in progress

IsTransitioning is the flag saying "this goal already started its advance logic". Even with several contacts, the same goal does not start the logic twice.

4. Record to the GameInstance, then open the next level

Wire after Set IsTransitioning = true into Cast To BP_GameInstance 's white exec input. Pass Get Game Instance 's blue Return Value to the Cast's Object.

Passing the white exec wire and Get Game Instance's reference separately into the Cast

Get Game Instance has no white exec pins. White wires carry "when to run" and blue wires carry "which target to use".

From the Cast's success, continue to the ClearStage call. Pass "As BP Game Instance" to Target, a Get of your own StageID to StageID, and a Get of your own StageScore to Score.

Passing the goal's own StageID and score to ClearStage with the GameInstance as Target

From ClearStage's white output, continue to Open Level (by Name) . Pass a Get of NextLevel to Level Name, set Absolute to true, and leave Options empty.

Calling Open Level with NextLevel after ClearStage finishes

Record before leaving the current level . The next level then reads an already updated GameInstance.

On Cast To BP_GameInstance's failure side, wire Set IsTransitioning = false → Print Text showing Check the Game Instance Class . Do not continue to Open Level on failure. The character Cast's failure side does nothing, since it is out of scope.

5. Display the current record in the new level

Create BP_RunStatus with Actor as its parent and place one in all four levels. No visual components are needed.

In BP_RunStatus, wire BeginPlay → Cast To BP_GameInstance with Get Game Instance's output into Object. From success, call ShowSummary with "As BP Game Instance" as Target. The failure side prints the same setting-check message.

Each level's BP_RunStatus calling the GameInstance's ShowSummary on BeginPlay

Do not reset TotalScore to 0 each time you display it. BP_RunStatus reads the record; it is not the thing that initializes it.

Sponsored

Confirm: carry-over, revisit, and a new run

First, play through three stages

Save and compile everything and Play from L_Stage01. Click the screen to control, and walk to each goal pillar in turn.

MomentDisplayed record
Starting L_Stage01Total: 0 / Cleared: 0
Clearing Stage01 into L_Stage02Total: 120 / Cleared: 1
Clearing Stage02 into L_Stage03Total: 200 / Cleared: 2
Clearing Stage03 into L_ResultTotal: 350 / Cleared: 3
Three clears building 120, 200, and 350, with 350 and 3 remaining at the result screen

Even if you miss the text right before a transition, the next level's BeginPlay shows it again. The same record also stays in the Output Log.

Revisit with the record kept

For testing, set BP_RunStatus' "Class Defaults → Input → Auto Receive Input" to Player 0. Add a keyboard R to the event graph and wire Pressed to Open Level (by Name). Enter /Game/Maps/L_Stage01 directly into Level Name.

Play through the three stages again and press R at the result. Reopening the first stage keeps the record at 350 / 3. Passing the goal again prints "already recorded" and advancing does not increase the score.

That confirms both that GameInstance persists and that duplicate scoring for the same StageID is prevented.

Start a new run by clearing the record

Create a function ResetRun on BP_GameInstance. From the entry, wire Set TotalScore = 0 → Clear → ShowSummary. Clear is the array node created from a Get of ClearedStages, emptying the list.

Add a keyboard N to BP_RunStatus. Pressed → Cast To BP_GameInstance with Object from Get Game Instance. From success, call ResetRun with "As BP Game Instance" as Target. Then call Open Level (by Name) opening /Game/Maps/L_Stage01 . Wire the setting-check message to the Cast failure side.

R returns to the first stage keeping the record, while N calls ResetRun for 0 and an empty list first

Pressing N during Play starts at 0 / 0, and playing through three stages again gives 350 / 3. That shows opening a level and starting a new run are separate operations .

Finally, stop and restart Play and the GameInstance itself is new, starting from the default 0 / 0. R and N are test controls; in production they become "Continue" and "New game" on a title screen.

When it does not work

SymptomWhere to look first
The setting-check message appearsWhether Game Instance Class is BP_GameInstance, and whether you restarted Play after setting it
The goal does not react when you approachTrigger and Capsule Overlap settings, Other Actor → Object, the white wire after the Cast
It does not advance to the next levelThe placed goal's NextLevel, where the levels are saved, Open Level's input
It reads 0 in the next levelWhether something initializes it on BeginPlay, or whether you read a different level variable
The second goal also says already recordedWhether each instance's StageID is Stage01 / 02 / 03
Revisiting increases only the scoreWhether Contains Item's True side continues to the addition
R or N does not respondWhether BP_RunStatus is placed, whether Auto Receive Input is Player 0, whether the screen has input focus

To test what registration means, stop Play, set Game Instance Class back to the default GameInstance, and play. The setting-check message should appear. Set it back to BP_GameInstance and restart Play afterwards.

Bonus: initialization and choosing what to store

Init and Shutdown differ from level start and end

GameInstance's event graph offers Event Init and Event Shutdown, the entry points for the GameInstance initializing and ending.

Wiring Init → Print Text with GameInstance: Init and Shutdown → Print Text with GameInstance: Shutdown to the log lets you trace the difference between Play start and stop and level transitions. Playing through three stages does not call Init again per level.

Init is where you prepare values needed at startup. Do not touch things assuming the player and UI exist; reflect things onto screens and Actors once each is ready. And Shutdown is not guaranteed on a forced quit, so do not rely on it alone for important saving.

Store information that still means something in the next level

We kept a total score and stage IDs. We did not store a reference to "the goal Actor that was in L_Stage01".

Contrasting a reference to a goal Actor that disappears with the StageID and score that survive and remain usable

An Actor reference names "this specific instance that exists now". Referencing it from the GameInstance does not keep an Actor destroyed when you leave the level. Fetch the target you need in the next level, in that level.

What you want to carryExample record
How many points earnedTotalScore = 350
Where you clearedStage01, Stage02, Stage03
What you carryItem IDs and counts
Where to returnLevel name and checkpoint ID

You do not need to forbid all references. Some, such as references to Data Assets authored at design time, differ in nature from temporary level Actors. Choose by thinking about how long the referenced thing exists . Storing an ID does not automatically restore an Actor either; you still need logic finding or creating what corresponds to that ID.

For the next launch, use Save Game

GameInstance is "memory for this play session" and saving to Save Game is "a record passed to the next one". Update the GameInstance during play, and at checkpoints copy the values you need into a SaveGame object and write it to a file. Next time, read the file's values back into the GameInstance.

Creating a SaveGame object does not save a file. Try writing and reading back in the Save Game article.

When features grow, split by responsibility

When score, volume, achievements, and saving all gather into one class and it gets hard to tell where to make a change, consider splitting by feature. A GameInstance Subsystem , managed alongside the GameInstance, is one option.

You do not need it from the start. Gathering change entry points into ClearStage and ResetRun as we did keeps update rules easy to find. The C++ entry point for splitting is covered in the Subsystem article.

If you package it for testing, include all four levels in the build. Opening by name does not help if the map is not in the shipped build. Check the packaging article.

Summary

  • GameInstance is memory persisting throughout this play session
  • Creating it is not enough; it only works once registered in Project Settings
  • Store "information that still means something in the next level". Do not store Actor references
  • When to reset to 0 is yours to decide, based on where a run begins

The question when unsure where to store something is "does this still mean anything in the next level?" If not, holding it within that level is enough.

To keep it for the next launch, go to Save Game; to split by feature, go to Subsystem.

Reference: GameInstance official API, Get Game Instance, Open Level (by Name).

Unreal Engine Notes in this section98