What is the purpose of a UObject's Outer?

I’ve been reading the internals of the CoreUObject module to understand some of the core mechanisms that make Unreal Engine’s reflection, garbage collection and serialization work. Something I haven’t been able to fully grasp yet is the purpose of a UObject’s outer reference. It appears to have many uses throughout UE, here are two that I am aware of so far:

  • Creating a object serialization hierarchy, with a UPackage at its root. UObjects instantiated at runtime appear to use GetTransientPackage() as their outer. It’s unclear to me why UObjects need to be associated with a package and why an in-memory transient package is needed.
  • The Gameplay Framework uses the outer reference extensively to describe the hierarchy of world → level → actors → actor components. Having this reference is clearly needed in cases where children need to look up their current world. However it’s unclear to me why this was a necessary design choice at the core of the UObject system and not just a reference member variable added to Actor.

I would love to understand the core reasons why every UObject has an outer and why it isn’t a feature that exists in higher level APIs, like the Gameplay framework. If someone could give a first-principles overview, it would be very useful to me and the community, because there’s nothing I can find on Google that describes this. Thanks!

1 Like

In general I would say its a mechnism to model a “containment relationship” tree between UObjects, kind of like directories and files. Try searching the code for GetOuter() to see examples of usage.

Also, I wouldn’t go looking too hard to look for meticulously curated module boundaries between UObject and Engine. :slight_smile: A lot of stuff has leaked (in my humble opinion), and I think UObject is now a fairly inextricable part of Engine.

Also I will mention quickly that one of the most useful videos I watched when I first started learning about UE internals was Alex Forsythe’s “from init to main” (and hes made a few other really useful videos on unreal)…

4 Likes

The Outer member defines object ownership, and ultimatly the package the object will be saved in, with one exception: external packages. Objects car define a package to be saved in, even if their Outer is saved in another package. This is used for external actors and other object types.

Also, the Outer chain is used to determine if an object will be duplicated or not during duplication; when duplicating a World, all objects rooted in the World through their Outer chain will also be duplicated. For example, during World duplication, a normal texture asset will not be duplicated, but if that texture is Outered to an actor, it will be duplicated.

2 Likes

Thanks for taking the time to answer!

Could you give a little more color on External Packages? I see them referenced a lot in the UPackage system, but it’s not clear to me what they actually are at a high level. When are they typically used? Are they used by the typical game project or much lower level?

This is a good video, but it doesn’t go into the UObject system at all. It mainly describes the gameplay framework.

Normally, to know in which package an objet will be saved, you walk the outer chain until you find a package. Since UE5, an object can be saved in a different package, by overriding the package at any level in the outer chain. This is mainly used for the one file per actor feature, where actors are saved in their own package instead of their owning umap file to allow multiple persons to work on the same map at the same time.

1 Like

oo my god