unreal
SKILL.md
Unreal Engine Development Skill
Engine Detection
Look for: .uproject, .Build.cs, .uplugin, Source/, Content/, Config/DefaultEngine.ini, Binaries/
Project Structure
MyGame/
Source/
MyGame/
Public/ # Headers (.h)
Player/
Enemies/
UI/
Systems/
Private/ # Implementation (.cpp)
Player/
Enemies/
UI/
Systems/
MyGame.Build.cs
MyGame.h
Content/
Blueprints/
Maps/
Materials/
Textures/
Meshes/
Audio/
UI/
Config/
DefaultEngine.ini
DefaultGame.ini
DefaultInput.ini
Plugins/
MyGame.uproject
Actor/Component Architecture
Unreal uses an Actor/Component model. Actors are placed in the world, Components add functionality:
// Header - Public/Player/MyCharacter.h
UCLASS()
class MYGAME_API AMyCharacter : public ACharacter
{
GENERATED_BODY()
public:
AMyCharacter();
protected:
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(UInputComponent* Input) override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float MaxHealth = 100.f;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UHealthComponent* HealthComponent;
UFUNCTION(BlueprintCallable, Category = "Combat")
void TakeDamage(float Amount, AActor* DamageCauser);
private:
UPROPERTY()
float CurrentHealth;
};
// Implementation - Private/Player/MyCharacter.cpp
AMyCharacter::AMyCharacter()
{
PrimaryActorTick.bCanEverTick = true;
HealthComponent = CreateDefaultSubobject<UHealthComponent>(TEXT("HealthComp"));
}
void AMyCharacter::BeginPlay()
{
Super::BeginPlay();
CurrentHealth = MaxHealth;
}
UPROPERTY Specifiers
// Editable in editor, readable/writable in Blueprints
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float Speed;
// Only visible in editor, read-only in Blueprints
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
USceneComponent* Root;
// Replicated for multiplayer
UPROPERTY(Replicated)
int32 Score;
// Replicated with notification
UPROPERTY(ReplicatedUsing = OnRep_Health)
float Health;
Blueprints vs C++ Decision Guide
Use C++ for:
- Core gameplay systems and base classes
- Performance-critical code (AI, physics, networking)
- Complex algorithms and data structures
- Low-level engine interaction
- Systems other programmers will extend
Use Blueprints for:
- Level-specific scripting and sequences
- UI logic and widget behavior
- Quick prototyping and iteration
- Designer-tunable parameters
- Visual effects and animation triggers
Best pattern: C++ base class + Blueprint child class
// C++ base with BlueprintNativeEvent
UFUNCTION(BlueprintNativeEvent, Category = "Combat")
void OnDeath();
void OnDeath_Implementation(); // Default C++ behavior, overridable in BP
Gameplay Ability System (GAS)
For complex ability/effect systems:
// Ability
UCLASS()
class UGA_FireBall : public UGameplayAbility
{
GENERATED_BODY()
public:
virtual void ActivateAbility(...) override;
virtual void EndAbility(...) override;
virtual bool CanActivateAbility(...) const override;
};
// Gameplay Effect for damage
UCLASS()
class UGE_FireDamage : public UGameplayEffect
{
// Configure in editor: damage value, duration, tags
};
Delegates & Events
// Single-cast delegate
DECLARE_DELEGATE_OneParam(FOnHealthChanged, float);
// Multi-cast delegate (Blueprint compatible)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHealthChangedDynamic, float, NewHealth);
// Usage in class
UPROPERTY(BlueprintAssignable)
FOnHealthChangedDynamic OnHealthChanged;
// Broadcast
OnHealthChanged.Broadcast(CurrentHealth);
Enhanced Input System
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInput)
{
auto* EIC = CastChecked<UEnhancedInputComponent>(PlayerInput);
EIC->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::Move);
EIC->BindAction(JumpAction, ETriggerEvent::Started, this, &AMyCharacter::StartJump);
}
Key Rules
- Always use UPROPERTY for UObject pointers - Prevents garbage collection of referenced objects
- Call Super:: on overridden functions - BeginPlay, Tick, EndPlay all need Super calls
- Use GENERATED_BODY() in all UCLASS/USTRUCT - Required for reflection
- Use soft references for large assets -
TSoftObjectPtr<UTexture2D>loads on demand - Disable Tick when not needed -
PrimaryActorTick.bCanEverTick = false - Use timers over Tick for periodic logic -
GetWorldTimerManager().SetTimer() - Use const references for FString parameters -
void Foo(const FString& Name) - Forward declare in headers, include in cpp - Faster compile times
- Use IsValid() checks - Not just null checks, also checks pending kill
- Profile with Unreal Insights - Built-in profiling for CPU, GPU, memory
Common Anti-Patterns
Cast<>in Tick without caching - expensive and repeated- Raw pointers to UObjects without UPROPERTY - GC can collect them
- Tick enabled on actors that don't need per-frame updates
- Loading assets synchronously on the game thread
- Not calling Super in lifecycle overrides
Multiplayer Patterns
// Server-authoritative function
UFUNCTION(Server, Reliable)
void ServerFireWeapon(FVector Direction);
// Multicast to all clients
UFUNCTION(NetMulticast, Unreliable)
void MulticastPlayFireEffect();
// Client-only
UFUNCTION(Client, Reliable)
void ClientShowDamageNumber(float Amount);
// Replication conditions
void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutProps) const override
{
Super::GetLifetimeReplicatedProps(OutProps);
DOREPLIFETIME_CONDITION(AMyCharacter, Health, COND_OwnerOnly);
}
Weekly Installs
3
Repository
davincidreams/a…-pluginsGitHub Stars
2
First Seen
Feb 14, 2026
Security Audits
Installed on
opencode3
github-copilot3
codex3
kimi-cli3
gemini-cli3
amp3