What the class prefixes mean, choosing a base type, what Blueprint can see, and why Unreal inherits the way it does.
The prefix tells you what a type is, and Unreal Header Tool (UHT) enforces that it matches the actual base type — get it wrong and it won't compile.
| Prefix | Meaning | Notes & examples |
|---|---|---|
| U | UObject-derived, not an Actor | GC-managed and reflected — UActorComponent, UTexture2D |
| A | Actor-derived | Can be placed or spawned in a level — AActor, APawn, ACharacter |
| F | Plain struct / non-UObject class | No engine lifecycle — FVector, FString, FStreamableHandle |
| T | Template | TArray, TMap, TSoftObjectPtr, TSubclassOf |
| I | Interface | Abstract base you inherit from — IAbilitySystemInterface |
| E | Enum | EPrimaryAssetType, EGameFeatureState |
| S | Slate widget (C++ UI) | SButton, SWidget |
| b | Boolean variable | Not a class prefix — bIsActive, bReplicates |
U = engine-managed object, A = lives in the world, F = plain data, T = generic container.
UCLASS() → always a GC-managed UObject; always a U or A prefix.USTRUCT() → reflection-only. Still a plain value type with an F prefix. No garbage collection, no lifecycle.| Base | Pick it when | Cost profile |
|---|---|---|
| F struct | Plain data — no instances or inheritance needed | Cheapest and cache-friendly; best for large arrays of data |
| UObject | Needs GC, reflection, or to be spawned without a world presence | Engine lifecycle overhead, but fully managed |
| AActor | Needs to exist in the level — transform, spawning, components | Heaviest; carries the full actor machinery |
Ask the questions in order. Does it need to be in the world? Then Actor. Does it need reflection or GC? Then UObject. Otherwise it's data, and a struct is both simpler and faster.
Blueprint supports int32, uint8, bool, float, double, FString, FName and FText.
uint16 and uint32 are not Blueprint-exposable. If a designer needs to see or set the value, it cannot live in one of those types.
Unreal almost always uses public inheritance, because the reflection system, Cast<T>(), and the component model all rely on the "IS-A" relationship.
Private or protected inheritance would break Cast<>, since the base type wouldn't be visible from outside the class. In an engine where casting and reflection are load-bearing, that isn't a stylistic choice — it's a requirement.
UCLASS / UPROPERTY / UFUNCTION macros before the C++ compiler does. Those macros are declaration-only in the .h; the .cpp is plain C++.f literal suffix. FVector now uses double internally in UE5, so writing 1.0f for its components is unnecessary — and slightly wrong.