Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Unreal Engine integration skill for C++/Blueprint development, actor lifecycle management, plugin development, and editor automation. Enables LLMs to interact with Unreal Editor through MCP servers for level manipulation, Blueprint generation, and automated workflows.
.claude/skills/a5c-ai-unreal-development/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 103% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 89% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 124% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 96% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 182% | 0% |
Comprehensive Unreal Engine development integration for AI-assisted game creation, editor automation, and project management.
This skill provides capabilities for interacting with Unreal Engine projects, including C++ development, Blueprint visual scripting, actor management, and build automation. It leverages the Unreal MCP ecosystem for direct editor integration when available.
For direct Unreal Editor integration:
json{ "mcpServers": { "unreal": { "command": "python", "args": ["-m", "unreal_mcp"], "env": { "UNREAL_PROJECT_PATH": "/path/to/project.uproject" } } } }
Alternative MCP servers:
UnrealMCP (kvick-games) - TCP server with JSON commandsunreal-mcp (chongdashu) - Natural language controlUnreal_mcp (ChiR24) - C++ Automation Bridgecpp// MyCharacter.h #pragma once #include "CoreMinimal.h" #include "GameFramework/Character.h" #include "MyCharacter.generated.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(class UInputComponent* PlayerInputComponent) override; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement") float MoveSpeed = 600.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement") float JumpHeight = 420.0f; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components") class UCameraComponent* CameraComponent; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components") class USpringArmComponent* SpringArmComponent; private: void MoveForward(float Value); void MoveRight(float Value); void StartJump(); void StopJump(); };
cpp// MyCharacter.cpp #include "MyCharacter.h" #include "Camera/CameraComponent.h" #include "GameFramework/SpringArmComponent.h" #include "GameFramework/CharacterMovementComponent.h" AMyCharacter::AMyCharacter() { PrimaryActorTick.bCanEverTick = true; // Create spring arm SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArm")); SpringArmComponent->SetupAttachment(RootComponent); SpringArmComponent->TargetArmLength = 400.0f; SpringArmComponent->bUsePawnControlRotation = true; // Create camera CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera")); CameraComponent->SetupAttachment(SpringArmComponent); // Configure movement GetCharacterMovement()->MaxWalkSpeed = MoveSpeed; GetCharacterMovement()->JumpZVelocity = JumpHeight; } void AMyCharacter::BeginPlay() { Super::BeginPlay(); } void AMyCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); } void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); PlayerInputComponent->BindAxis("MoveForward", this, &AMyCharacter::MoveForward); PlayerInputComponent->BindAxis("MoveRight", this, &AMyCharacter::MoveRight); PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AMyCharacter::StartJump); PlayerInputComponent->BindAction("Jump", IE_Released, this, &AMyCharacter::StopJump); } void AMyCharacter::MoveForward(float Value) { if (Value != 0.0f) { const FRotator Rotation = Controller->GetControlRotation(); const FRotator YawRotation(0, Rotation.Yaw, 0); const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); AddMovementInput(Direction, Value); } } void AMyCharacter::MoveRight(float Value) { if (Value != 0.0f) { const FRotator Rotation = Controller->GetControlRotation(); const FRotator YawRotation(0, Rotation.Yaw, 0); const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); AddMovementInput(Direction, Value); } } void AMyCharacter::StartJump() { Jump(); } void AMyCharacter::StopJump() { StopJumping(); }
cpp// EnemyDataAsset.h #pragma once #include "CoreMinimal.h" #include "Engine/DataAsset.h" #include "EnemyDataAsset.generated.h" UENUM(BlueprintType) enum class EEnemyType : uint8 { Melee, Ranged, Boss }; UCLASS(BlueprintType) class MYGAME_API UEnemyDataAsset : public UPrimaryDataAsset { GENERATED_BODY() public: UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Basic Info") FString EnemyName; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Basic Info") EEnemyType EnemyType; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Stats") float MaxHealth = 100.0f; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Stats") float MoveSpeed = 300.0f; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Combat") float AttackDamage = 10.0f; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Combat") float AttackRange = 150.0f; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Visuals") TObjectPtr<USkeletalMesh> Mesh; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Visuals") TObjectPtr<UAnimBlueprint> AnimBlueprint; // UPrimaryDataAsset interface virtual FPrimaryAssetId GetPrimaryAssetId() const override; };
cpp// MyGameplayAbility.h #pragma once #include "CoreMinimal.h" #include "Abilities/GameplayAbility.h" #include "MyGameplayAbility.generated.h" UCLASS() class MYGAME_API UMyGameplayAbility : public UGameplayAbility { GENERATED_BODY() public: UMyGameplayAbility(); UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Ability") float CooldownDuration = 1.0f; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Ability") float ManaCost = 10.0f; protected: virtual void ActivateAbility( const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override; virtual void EndAbility( const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override; };
javascriptconst unrealActorTask = defineTask({ name: 'unreal-actor-generation', description: 'Generate Unreal Engine Actor class', inputs: { actorType: { type: 'string', required: true }, // Character, Pawn, Actor className: { type: 'string', required: true }, components: { type: 'array', required: true }, outputPath: { type: 'string', required: true } }, outputs: { headerPath: { type: 'string' }, sourcePath: { type: 'string' }, success: { type: 'boolean' } }, async run(inputs, taskCtx) { return { kind: 'skill', title: `Generate Unreal Actor: ${inputs.className}`, skill: { name: 'unreal-development', context: { operation: 'generate_actor', actorType: inputs.actorType, className: inputs.className, components: inputs.components, outputPath: inputs.outputPath } }, io: { inputJsonPath: `tasks/${taskCtx.effectId}/input.json`, outputJsonPath: `tasks/${taskCtx.effectId}/result.json` } }; } });
| Tool | Description | |------|-------------| | unreal_spawn_actor | Spawn actor in level | | unreal_modify_actor | Modify actor properties | | unreal_create_blueprint | Generate Blueprint class | | unreal_compile | Trigger hot reload/compile | | unreal_build | Build for target platform | | unreal_run_automation | Execute automation tests | | unreal_query_level | Get level structure | | unreal_python_exec | Execute Unreal Python command |
json{ "mcpServers": { "unreal": { "command": "python", "args": ["-m", "unreal_mcp"], "env": { "UNREAL_PROJECT_PATH": "C:/Projects/MyGame/MyGame.uproject", "UNREAL_ENGINE_PATH": "C:/Program Files/Epic Games/UE_5.3" } } } }
| Platform | Key Considerations | |----------|-------------------| | PC | Full feature support, shader model 5+ | | Console | Memory budgets, certification requirements | | Mobile | Simplified rendering, thermal management | | VR | Frame rate requirements, motion sickness prevention |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 13,111 | 18,277 | +39% | 1 | 1 | 0% | 2,688 | 5,456 | +103% | 0 | 0 | — |
case-02 | fail→fail | 15,075 | 13,038 | -14% | 1 | 1 | 0% | 2,603 | 5,431 | +109% | 0 | 0 | — |
case-03 | fail→pass | 16,042 | 9,598 | -40% | 1 | 1 | 0% | 2,551 | 4,829 | +89% | 0 | 0 | — |
case-04 | fail→fail | 24,210 | 20,518 | -15% | 1 | 1 | 0% | 4,580 | 6,235 | +36% | 0 | 0 | — |
case-05 | pass→pass | 12,835 | 14,077 | +10% | 1 | 1 | 0% | 2,405 | 5,198 | +116% | 0 | 0 | — |
case-06 | fail→pass | 13,602 | 11,512 | -15% | 1 | 1 | 0% | 2,285 | 5,117 | +124% | 0 | 0 | — |
case-07 | pass→pass | 10,895 | 10,450 | -4% | 1 | 1 | 0% | 2,170 | 4,976 | +129% | 0 | 0 | — |
case-08 | pass→pass | 12,102 | 13,920 | +15% | 1 | 1 | 0% | 2,183 | 5,119 | +134% | 0 | 0 | — |
case-09 | pass→pass | 6,221 | 7,832 | +26% | 1 | 1 | 0% | 1,146 | 4,137 | +261% | 0 | 0 | — |
case-10 | pass→pass | 8,577 | 7,642 | -11% | 1 | 1 | 0% | 1,418 | 4,440 | +213% | 0 | 0 | — |
case-11 | pass→pass | 11,896 | 14,909 | +25% | 1 | 1 | 0% | 1,787 | 5,353 | +200% | 0 | 0 | — |
case-12 | fail→fail | 16,457 | 18,304 | +11% | 1 | 1 | 0% | 3,136 | 6,035 | +92% | 0 | 0 | — |
case-13 | pass→pass | 7,420 | 6,425 | -13% | 1 | 1 | 0% | 1,321 | 4,248 | +222% | 0 | 0 | — |
case-14 | fail→pass | 10,565 | 2,501 | -76% | 1 | 1 | 0% | 1,765 | 3,462 | +96% | 0 | 0 | — |
case-15 | fail→pass | 7,594 | 4,603 | -39% | 1 | 1 | 0% | 1,287 | 3,631 | +182% | 0 | 0 | — |
case-16 | pass→pass | 12,402 | 17,527 | +41% | 1 | 1 | 0% | 2,222 | 5,299 | +138% | 0 | 0 | — |
case-17 | pass→pass | 4,200 | 5,847 | +39% | 1 | 1 | 0% | 486 | 3,665 | +654% | 0 | 0 | — |
case-18 | fail→pass | 14,592 | 7,331 | -50% | 1 | 1 | 0% | 2,201 | 4,286 | +95% | 0 | 0 | — |
case-19 | pass→pass | 14,491 | 13,597 | -6% | 1 | 1 | 0% | 2,034 | 5,003 | +146% | 0 | 0 | — |
case-20 | fail→pass | 11,715 | 2,404 | -79% | 1 | 1 | 0% | 1,672 | 3,423 | +105% | 0 | 0 | — |
case-21 | pass→pass | 7,164 | 10,028 | +40% | 1 | 1 | 0% | 1,364 | 4,595 | +237% | 0 | 0 | — |
case-22 | pass→pass | 13,826 | 10,022 | -28% | 1 | 1 | 0% | 2,161 | 4,695 | +117% | 0 | 0 | — |
case-23 | pass→pass | 13,042 | 9,186 | -30% | 1 | 1 | 0% | 2,146 | 4,827 | +125% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +30 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.