Course contentsShow
← Unreal Engine Game Development
Lesson 153 of 8802. The Gameplay FrameworkFree lesson

Synchronizing GameInstance Data with PlayerController Initialization

You will create a workflow to initialize player stats and inventory by pulling saved data from the GameInstance upon level start.

In this lesson, you will learn how to bridge the gap between persistent data stored in your GameInstance and a newly spawned PlayerController to ensure your player starts the level with the correct stats and inventory.

The Lifecycle Challenge

When a player travels to a new level, the GameInstance persists, but the PlayerController is destroyed and recreated. If you simply leave your inventory logic in the PlayerController, it will reset to default values every time the player loads a map. To solve this, we treat the GameInstance as our "Source of Truth" and initialize the PlayerController immediately upon its creation.

Implementing the Workflow

The most reliable time to pull this data is during the BeginPlay event of your PlayerController. Because the GameInstance exists globally, your controller can cast to your custom GameInstance class to retrieve the saved data.

Here is a conceptual flow for your PlayerController's BeginPlay:

void AMyPlayerController::BeginPlay()
{
    Super::BeginPlay();

    // 1. Access the persistent GameInstance
    UMyGameInstance* GI = Cast<UMyGameInstance>(GetGameInstance());

    if (GI)
    {
        // 2. Pull data from the GameInstance
        this->CurrentHealth = GI->SavedHealth;
        this->PlayerInventory = GI->SavedInventory;

        // 3. Update the UI or Pawn to reflect these values
        UpdateHUD(CurrentHealth);
    }
}

Why this Order Matters

By waiting until BeginPlay, you ensure the PlayerController has successfully possessed the pawn and initialized its own systems. If you try to access the GameInstance too early—such as in the constructor—the controller may not be fully registered with the world, leading to null pointer errors.

Using this pattern, you keep the GameInstance responsible for storing long-term state across level transitions, while the PlayerController remains responsible for applying that state to the current gameplay session. This separation of concerns ensures that your data flows predictably as the player moves through your world.

Key Takeaway: Always treat your GameInstance as the persistent data repository and use the PlayerController’s BeginPlay event as the trigger to synchronize that state into the active gameplay session.