In this lesson, you will learn how to determine whether your data belongs in the UObject garbage collection system or should be managed via C++ smart pointers.
The Architectural Divide
The most common mistake beginners make is trying to treat everything as a UObject. In Unreal, you must categorize your data based on its relationship with the Engine's reflection system.
Use UObject (Garbage Collection) when:
- You need reflection, such as exposing properties to Blueprints via
UPROPERTY. - The object is inherently part of the game world (like an
AActoror an inventory item that needs to be saved/serialized). - The object interacts with Engine systems like the
World,Tick, orLevel.
Use Smart Pointers (TSharedPtr, TUniquePtr) when:
- The data is "pure" C++ logic, such as a complex math library, a custom data structure for an algorithm, or a private plugin helper.
- The object does not need to be seen by Blueprints or the Editor’s reflection system.
- You require deterministic destruction (immediate memory release) rather than waiting for the next Garbage Collection sweep.
A Practical Scenario
Imagine you are building a Quest System.
If your Quest needs to show progress bars in a UI widget created in Blueprints, it must inherit from UObject and use UPROPERTY pointers so the garbage collector knows it’s in use.
However, if you are building an A Pathfinding Algorithm* that calculates paths using temporary nodes, these nodes should not be UObjects. Creating thousands of UObjects per frame for temporary calculations will trigger frequent, expensive garbage collection spikes. Instead, use TUniquePtr or TSharedPtr for these transient objects to keep them off the heap and ensure they clean themselves up immediately when the function ends.
The Decision Checklist
- Does it need to be a
UPROPERTY? Yes -> UseUObject. - Is it a short-lived calculation? Yes -> Use Smart Pointers.
- Is it heavy/persistent gameplay data? Yes -> Use
UObject.
Mixing these approaches correctly keeps your game fast while leveraging the Engine's powerful reflection tools where they provide the most value.
Key Takeaway: Choose UObject for reflected, gameplay-exposed objects and C++ smart pointers for high-performance, non-reflected logic to avoid unnecessary garbage collection overhead.