All skills
gamedev-skills avatar

/unreal-cpp-gameplay

@3727d02

Write Unreal Engine 5 C++ gameplay code: the UCLASS/UPROPERTY/UFUNCTION reflection macros, the Gameplay Framework (GameMode, Pawn, Character, PlayerController, Actor components), and the module Build.cs. Use when writing or debugging UE C++, deriving from AActor/ACharacter/ AGameModeBase, exposing properties to the editor or Blueprints, or when the user mentions Unreal C++, UCLASS, GENERATED_BODY, GameMode, ACharacter, or .Build.cs.

Use this Skill: https://skilld.dev/gh/gamedev-skills/awesome-gamedev-agent-skills/unreal-cpp-gameplay

This session only. Nothing lands on disk.

referencescomponents-and-gc.md

≈1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Components, garbage collection & replication primer (UE 5.8 C++)

Depth for unreal-cpp-gameplay. Verified against the Gameplay Framework docs and the UE5 C++ programming references. Covers component creation/attachment, the UPROPERTY/GC ownership rules that trip up newcomers, and a minimal replication example.

Creating and attaching components

Default subobjects are created in the constructor; runtime components use NewObject + RegisterComponent.

// In the constructor — built into the Class Default Object, editable in the Blueprint subclass.
ACharacterBase::ACharacterBase()
{
    SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm"));
    SpringArm->SetupAttachment(RootComponent);          // attach to an existing component
    SpringArm->TargetArmLength = 300.f;

    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
    Camera->SetupAttachment(SpringArm);                 // socket chain: root -> arm -> camera
}
// At runtime (e.g. add a component after spawn):
UAudioComponent* Audio = NewObject<UAudioComponent>(this);
Audio->RegisterComponent();                              // required, or it won't tick/render
Audio->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
  • CreateDefaultSubobject is only valid in a constructor; using it later asserts.
  • SetupAttachment is for constructor-time hierarchy; AttachToComponent is the runtime call.

Garbage collection ownership (the #1 newcomer crash)

The UE garbage collector only keeps UObjects alive if it can reach them through a reflected reference. A raw UObject* member that isn't a UPROPERTY is invisible to the GC and can be collected, leaving a dangling pointer.

UPROPERTY()                                  // GC sees it -> stays alive while this owner lives
TObjectPtr<UMyDataObject> Data;

UPROPERTY()
TArray<TObjectPtr<AActor>> Tracked;          // containers of UObjects also need UPROPERTY

UMyDataObject* Raw;                           // BUG: not tracked; may be GC'd -> crash

Rules:

  • Every UObject/Actor pointer that must persist gets a UPROPERTY (use TObjectPtr<T> in UE5; raw pointers still compile but TObjectPtr adds access tracking in the editor).
  • Plain C++ data (ints, FStrings, FVectors, USTRUCTs of POD) doesn't need this — it's owned by value.
  • For a UObject you create that has no UPROPERTY owner (rare), AddToRoot() pins it and RemoveFromRoot() releases it — but prefer proper ownership.

USTRUCT and UENUM for reflected data

UENUM(BlueprintType)
enum class EWeaponType : uint8 { Pistol, Rifle, Shotgun };

USTRUCT(BlueprintType)
struct FWeaponStats
{
    GENERATED_BODY()
    UPROPERTY(EditAnywhere, BlueprintReadWrite) int32 Damage = 10;
    UPROPERTY(EditAnywhere, BlueprintReadWrite) float FireRate = 0.25f;
};

BlueprintType makes the enum/struct usable as Blueprint variables.

Minimal replication (multiplayer)

// Header
UPROPERTY(ReplicatedUsing = OnRep_Health)
float Health = 100.f;

UFUNCTION()
void OnRep_Health();                          // client callback when Health replicates

// Source
#include "Net/UnrealNetwork.h"
void AMyActor::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& Out) const
{
    Super::GetLifetimeReplicatedProps(Out);
    DOREPLIFETIME(AMyActor, Health);          // register the property for replication
}
  • Set bReplicates = true; in the constructor for the actor to replicate at all.
  • Server authority: gameplay changes happen on the server; clients receive replicated state and react in OnRep_ callbacks.

Gotchas

  • NewObject without RegisterComponent gives a component that exists but never ticks or renders.
  • Forgetting #include "Net/UnrealNetwork.h" breaks DOREPLIFETIME.
  • TObjectPtr implicitly converts to the raw pointer for calls, so existing ->/. usage is unchanged; the difference is GC visibility and editor tooling, not syntax at call sites.

Source: SKILL.md on GitHub

No alerts1mo3 checks · Risk SAFE
  • Gen Agent Trust Hub1mo

    The skill provides standard instructional documentation and code templates for Unreal Engine 5 C++ gameplay development. No security risks or malicious patterns were identified.

  • Socket1mo

    No alerts

  • Snyk1mo

    Risk: LOW · No issues

Signed by skilld at 3727d02. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 days ago.

Activeupdated 2 months ago

README badge

README badge for gamedev-skills/awesome-gamedev-agent-skills/unreal-cpp-gameplay