← SEARCHABLE ARCHIVE
Unreal Engine · 2026-07-05

Gather common features with GameInstanceSubsystem

How we centralized ProjectDT's UI flow

INTERACTIVE READING MODE →

The articles written on this blog were created with the goal of teaching. Also, the information in the article may be incorrect, so please be careful.

When multiple Widgets and Actors repeat the same UI task, the code to find each other directly increases. ProjectDT has a common UI flowUGameInstanceSubsystemcollected.

Why use Subsystem?

UGameInstanceSubsystemhas the same lifespan as GameInstance and is automatically created by the engine. You can get it from anywhere through GameInstance without having to create a separate Singleton pointer yourself.

UDTUISubsystem* UISubsystem =
    GetGameInstance()->GetSubsystem<UDTUISubsystem>();

if (UISubsystem)
{
    UISubsystem->ProcessSolvedProblem(
        ProblemData,
        FVector2D::ZeroVector,
        0.0f,
        100.0f
    );
}

Side effects, such as the dialogue that follows the problem answer processing and the creation of a whiteboard node, can be collected into one function rather than copied for each widget.

Don't put everything in

Subsystem is also easily accessible globally, so if you keep adding responsibilities, it becomes another huge manager class.

  • UI transitions and UI events are UI Subsystem
  • The save slot and current SaveGame are Save Subsystem
  • The current world win/loss rules are GameMode
  • Player input is PlayerController

If you hold on to a temporary Actor pointer during combat just because it has a long lifespan, old objects may remain after moving around the world. ProjectDT's MainUI and WhiteBoard references are:TWeakObjectPtrIt was stored as

Subsystems are good hubs that connect distant objects together. However, you must check whether the lifespan and responsibility of the data are really within the scope of GameInstance before using it.