Unreal Engine C++ Pro
Selective Reading Rule
Start with:
references/senior-master-standard.md
references/usage-routing.md
references/quality-checklist.md
Then load only the inherited docs, scripts, assets, or examples that match the user's actual task.
This skill provides expert-level guidelines for developing with Unreal Engine 5 using C++. It focuses on writing robust, performant, and standard-compliant code.
When to Use
Use this skill when:
- Developing C++ code for Unreal Engine 5.x projects
- Writing Actors, Components, or UObject-derived classes
- Optimizing performance-critical code in Unreal Engine
- Debugging memory leaks or garbage collection issues
- Implementing Blueprint-exposed functionality
- Following Epic Games' coding standards and conventions
- Working with Unreal's reflection system (UCLASS, USTRUCT, UFUNCTION)
- Managing asset loading and soft references
Do not use this skill when:
- Working with Blueprint-only projects (no C++ code)
- Developing for Unreal Engine versions prior to 5.x
- Working on non-Unreal game engines
- The task is unrelated to Unreal Engine development
Core Principles
UObject & Garbage Collection:
- Always use
UPROPERTY() for UObject* member variables to ensure they are tracked by the Garbage Collector (GC).
- Use
TStrongObjectPtr<> if you need to keep a root reference outside of a UObject graph, but prefer addToRoot() generally.
- Understand the
IsValid() check vs nullptr. IsValid() handles pending kill state safely.
Unreal Reflection System:
- Use
UCLASS(), USTRUCT(), UENUM(), UFUNCTION() to expose types to the reflection system and Blueprints.
- Minimize
BlueprintReadWrite when possible; prefer BlueprintReadOnly for state that shouldn't be trampled by logic in UI/Level BPs.
Performance First:
- Tick: Disable Ticking (
bCanEverTick = false) by default. Only enable it if absolutely necessary. Prefer timers (GetWorldTimerManager()) or event-driven logic.
- Casting: Avoid
Cast<T>() in hot loops. Cache references in BeginPlay.
- Structs vs Classes: Use
F structs for data-heavy, non-UObject types to reduce overhead.
Naming Conventions (Strict)
Follow Epic Games' coding standard:
- Templates: Prefix with
T (e.g., TArray, TMap).
- UObject: Prefix with
U (e.g., UCharacterMovementComponent).
- AActor: Prefix with
A (e.g., AMyGameMode).
- SWidget: Prefix with
S (Slate widgets).
- Structs: Prefix with
F (e.g., FVector).
- Enums: Prefix with
E (e.g., EWeaponState).
- Interfaces: Prefix with
I (e.g., IInteractable).
- Booleans: Prefix with
b (e.g., bIsDead).
Common Patterns
1. Robust Component Lookup
Avoid GetComponentByClass in Tick. Do it in PostInitializeComponents or BeginPlay.
void AMyCharacter::PostInitializeComponents() {
Super::PostInitializeComponents();
HealthComp = FindComponentByClass<UHealthComponent>();
check(HealthComp); // Fail hard in dev if missing
}
2. Interface Implementation
Use interfaces to decouple systems (e.g., Interaction system).
// Interface call check
if (TargetActor->Implements<UInteractable>()) {
IInteractable::Execute_OnInteract(TargetActor, this);
}
3. Async Loading (Soft References)
Avoid hard references (UPROPERTY(EditDefaultsOnly) TSubclassOf<AActor>) for massive assets which force load orders. Use TSoftClassPtr or TSoftObjectPtr.
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSoftClassPtr<AWeapon> WeaponClassToLoad;
void AMyCharacter::Equip() {
if (WeaponClassToLoad.IsPending()) {
WeaponClassToLoad.LoadSynchronous(); // Or use StreamableManager for async
}
}
Debugging
- Logging: Use
UE_LOG with custom categories.DEFINE_LOG_CATEGORY_STATIC(LogMyGame, Log, All);
UE_LOG(LogMyGame, Warning, TEXT("Health is low: %f"), CurrentHealth);
- Screen Messages:
if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Died!"));
- Visual Logger: extremely useful for AI debugging. Implement
IVisualLoggerDebugSnapshotInterface.
Checklist before PR
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
1---2name: unreal-engine-cpp-pro3description: ALWAYS use this when the request matches Unreal Engine CPP PRO: Expert guide for Unreal Engine 5.x C++ development, covering UObject hygiene, performance patterns, and best practices.4---56# Unreal Engine C++ Pro78## Selective Reading Rule910Start with:1112- `references/senior-master-standard.md`13- `references/usage-routing.md`14- `references/quality-checklist.md`1516Then load only the inherited docs, scripts, assets, or examples that match the user's actual task.1718This skill provides expert-level guidelines for developing with Unreal Engine 5 using C++. It focuses on writing robust, performant, and standard-compliant code.1920## When to Use21Use this skill when:22- Developing C++ code for Unreal Engine 5.x projects23- Writing Actors, Components, or UObject-derived classes24- Optimizing performance-critical code in Unreal Engine25- Debugging memory leaks or garbage collection issues26- Implementing Blueprint-exposed functionality27- Following Epic Games' coding standards and conventions28- Working with Unreal's reflection system (UCLASS, USTRUCT, UFUNCTION)29- Managing asset loading and soft references3031Do not use this skill when:32- Working with Blueprint-only projects (no C++ code)33- Developing for Unreal Engine versions prior to 5.x34- Working on non-Unreal game engines35- The task is unrelated to Unreal Engine development3637## Core Principles38391. **UObject & Garbage Collection**:40 * Always use `UPROPERTY()` for `UObject*` member variables to ensure they are tracked by the Garbage Collector (GC).41 * Use `TStrongObjectPtr<>` if you need to keep a root reference outside of a UObject graph, but prefer `addToRoot()` generally.42 * Understand the `IsValid()` check vs `nullptr`. `IsValid()` handles pending kill state safely.43442. **Unreal Reflection System**:45 * Use `UCLASS()`, `USTRUCT()`, `UENUM()`, `UFUNCTION()` to expose types to the reflection system and Blueprints.46 * Minimize `BlueprintReadWrite` when possible; prefer `BlueprintReadOnly` for state that shouldn't be trampled by logic in UI/Level BPs.47483. **Performance First**:49 * **Tick**: Disable Ticking (`bCanEverTick = false`) by default. Only enable it if absolutely necessary. Prefer timers (`GetWorldTimerManager()`) or event-driven logic.50 * **Casting**: Avoid `Cast<T>()` in hot loops. Cache references in `BeginPlay`.51 * **Structs vs Classes**: Use `F` structs for data-heavy, non-UObject types to reduce overhead.5253## Naming Conventions (Strict)5455Follow Epic Games' coding standard:5657* **Templates**: Prefix with `T` (e.g., `TArray`, `TMap`).58* **UObject**: Prefix with `U` (e.g., `UCharacterMovementComponent`).59* **AActor**: Prefix with `A` (e.g., `AMyGameMode`).60* **SWidget**: Prefix with `S` (Slate widgets).61* **Structs**: Prefix with `F` (e.g., `FVector`).62* **Enums**: Prefix with `E` (e.g., `EWeaponState`).63* **Interfaces**: Prefix with `I` (e.g., `IInteractable`).64* **Booleans**: Prefix with `b` (e.g., `bIsDead`).6566## Common Patterns6768### 1. Robust Component Lookup69Avoid `GetComponentByClass` in `Tick`. Do it in `PostInitializeComponents` or `BeginPlay`.7071```cpp72void AMyCharacter::PostInitializeComponents() {73 Super::PostInitializeComponents();74 HealthComp = FindComponentByClass<UHealthComponent>();75 check(HealthComp); // Fail hard in dev if missing76}77```7879### 2. Interface Implementation80Use interfaces to decouple systems (e.g., Interaction system).8182```cpp83// Interface call check84if (TargetActor->Implements<UInteractable>()) {85 IInteractable::Execute_OnInteract(TargetActor, this);86}87```8889### 3. Async Loading (Soft References)90Avoid hard references (`UPROPERTY(EditDefaultsOnly) TSubclassOf<AActor>`) for massive assets which force load orders. Use `TSoftClassPtr` or `TSoftObjectPtr`.9192```cpp93UPROPERTY(EditAnywhere, BlueprintReadWrite)94TSoftClassPtr<AWeapon> WeaponClassToLoad;9596void AMyCharacter::Equip() {97 if (WeaponClassToLoad.IsPending()) {98 WeaponClassToLoad.LoadSynchronous(); // Or use StreamableManager for async99 }100}101```102103## Debugging104105* **Logging**: Use `UE_LOG` with custom categories.106 ```cpp107 DEFINE_LOG_CATEGORY_STATIC(LogMyGame, Log, All);108 UE_LOG(LogMyGame, Warning, TEXT("Health is low: %f"), CurrentHealth);109 ```110* **Screen Messages**:111 ```cpp112 if (GEngine) GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Died!"));113 ```114* **Visual Logger**: extremely useful for AI debugging. Implement `IVisualLoggerDebugSnapshotInterface`.115116## Checklist before PR117118- [ ] Does this Actor need to Tick? Can it be a Timer?119- [ ] Are all `UObject*` members wrapped in `UPROPERTY`?120- [ ] Are hard references (TSubclassOf) causing load chains? Can they be Soft Ptrs?121- [ ] Did you clean up verified delegates in `EndPlay`?122123## Limitations124- Use this skill only when the task clearly matches the scope described above.125- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.126- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.