Skip to content

World Aware Getters

11/3/25

You ever just want access to some global system in Unreal and are you ever exhausted at how silly getting it might be? Like, imagine a subsystem or something that you want access to, but in order to get to it from something like a UObject you'll have to pull some verbose shit.

Let's say I have a subsystem, SomeGameInstanceSubsystem, and it's a UGameInstanceSubsystem. This means naturally I'm gonna get this thing off of the UGameInstance for my UWorld. If I have a UObject like a UUserWidget or an AActor, then I can probably reasonably get to the Game Instance by doing some stuff like:

c++
/** Assuming this is a valid Actor, spawned in the world */
AActor* MyActor;

UWorld* MyWorld = MyActor->GetWorld();
UGameInstance* MyGameInstance = MyWorld->GetGameInstance();
UGameInstanceSubsystem* MySubsystem = MyGameInstance->GetSubsystem<USomeGameInstanceSubsystem>();

... Okay so it's three lines. Three lines if you don't want to do any null checking and really just wanna go in expecting your shit to get rocked for no reason when playing the game.

We can abstract this by writing a function that'll take an object that is "World Aware"

World Awareness

World awareness is cool as hell. It refers to a term that some UObject, be it AActor, USceneComponent, or even UUserWidget have access to the world they've been created in. And it's a pretty wide reach of things.

But how? How can every object seem to know what UWorld it's in? and that's because of the outer chain. The outer chain is one of my favorite things, because I come from javascript, where it's a godless land and there's a gigantic fucking prototype chain that leads you all the way up to everything basically being an object.

The outer chain in unreal is a hierarchy of objects that, when followed all the way up from a simple UObject, you eventually get to UWorld.

Based on what I understand now, and what I've managed to search up, the chain is basically this: World -> Level -> Actors -> Components.

INFO

Just so you know: if you create a new object with GetTransientPackage() as the outer, it will not be world aware since it kind of just... exists outside of the chain.

How we write a world aware retrieval

Based on what we know about the outer chain and most objects just knowing about the UWorld they live in, we can write a static method that takes in a single world-aware context object.

c++
static USomeSubsystem* Get(UObject* InWorldAwareContextObject) {

    if(!IsValid(InWorldAwareContextObject)) {
        return;
    }

    const UWorld* World = InWorldAwareContextObject->GetWorld();

    if(!IsValid(World)) {
        /** Buddy you've got bigger problems if you're here. */
    }

    const UGameInstance* GameInstance = World->GetGameInstance();
}

We're basically hijacking the functionality of a broad number of objects that exist that know about their world, and piggybacking on that to return the primary instance of our subsystem!

Taking this a step further because in writing this I found this shit, we can probably use UGameplayStatics with our same world-aware object!

c++
static USomeSubsystem* Get(UObject* InWorldAwareContextObject) {

    if(!IsValid(InWorldAwareContextObject)) return;

    /** Oh hell yeah that's a one liner. */
    const UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(InWorldAwareContextObject);

    /** And a ternary? Stop it. STOP. */
    return IsValid(GameInstance) ? GameInstance->GetSubsystem<ThisClass>() : nullptr;
}

Final thoughts

I mean. That's it. This is a pattern you can use in almost anything that you'd like an easier time getting in a static way. This is mostly useful for subsystems or other "global" objects that sit somewhere in the world, level or player controller.

Really? Unreally! (terrible... I need a shower).

Painstakingly updated: