C++ Conversion Example - How Guided Conversion Works

This showcase walks through converting a Blueprint damage system to C++ using Claude AI. Showing how structured Blueprint context enables informed AI assistance.

What this demonstrates:
- How BP2AI captures complete Blueprint logic as structured text
- How clear architectural requirements guide AI output
- How you stay in control of the conversion process
- How to review and implement AI suggestions responsibly

The key point: This isn't magic code generation. BP2AI provides the Blueprint context, you specify what you want, the AI suggests solutions, and you decide what to implement. You're in charge of the architecture, requirements, and final decisions.

 

Try it yourself: Use our Blueprint trace and prompt with your preferred AI. Results may vary between different AI models, but the structured context gives you a solid starting point for guided conversion.

Remember: You control the requirements, you review the output, you implement the changes.

C++ Conversion Showcase

Player Takes Damage Custom Event

**Trace Start: PlayerTakesDamage
Custom Event** (CustomEvent)

```blueprint
* Event PlayerTakesDamage Args: (Damage:double)
    * Set Damage:double = PlayerTakesDamage.Damage
        * If ((CurrentShield > 0.0))
            |-- true:
            |   * Set ShieldDamage:double = (Damage * (1 - (ArmorPercentage / 100)))
            |       * Set RemainingDamage:double = FMax((ShieldDamage - CurrentShield), 0)
            |           * Set CurrentShield:double = FMax((CurrentShield - ShieldDamage), 0)
            |               * If ((RemainingDamage > 0.0))
            |                   |-- true:
            |                   |   * Set CurrentHealth:double = (CurrentHealth - RemainingDamage)
            |                   |       * If ((CurrentHealth <= 0.0))
            |                   |           |-- true:
            |                   |           |   * K2_DestroyActor(())
            |                   |           |       * [Path ends]
            |                   |           L-- false:
            |                   |               * PrintString((InString=(Health: + Conv_DoubleToString(InDouble=CurrentHealth))))
            |                   |                   * [Path ends]
            |                   L-- false:
            |                       * PrintString((InString=Shields absorbed all damage))
            |                           * [Path ends]
            L-- false:
                * Set ReducedDamage:double = (Damage * (1 - (ArmorPercentage / 100)))
                    * Set CurrentHealth:double = (CurrentHealth - ReducedDamage)
                        * If ((CurrentHealth <= 0.0))
                            |-- true:
                            |   * K2_DestroyActor(())
                            |       * [Path ends]
                            L-- false:
                                * PrintString((InString=(Health: + Conv_DoubleToString(InDouble=CurrentHealth))))
                                    * [Path ends]
```

AI Prompt

Please convert the following Blueprint logic to C++ following these specific requirements:

REQUIREMENTS:

  • Convert to UE C++ ActorComponent (reusable design)
  • Use proper UFUNCTION/UPROPERTY patterns
  • Include event delegates for UI/audio integration (OnHealthChanged, OnShieldChanged, OnDeath)
  • Optimize calculations for performance
  • Maintain exact logical equivalence to Blueprint

DO NOT INCLUDE:

  • Network replication (no DOREPLIFETIME, no OnRep functions, no Replicated properties)
  • Networking includes or SetIsReplicatedByDefault
  • Any multiplayer/networking features

FOCUS ON:

  • Clean component architecture
  • Local gameplay calculations only
  • Event system for other systems to subscribe to health changes
  • Professional UE C++ patterns

Here is the Blueprint trace:

Header File

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "HealthComponent.generated.h"

// Delegate declarations for event broadcasting
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHealthChanged, double, NewHealth);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnShieldChanged, double, NewShield);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDeath);

UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class YOURGAME_API UHealthComponent : public UActorComponent
{
    GENERATED_BODY()

public:
    UHealthComponent();

protected:
    // Health and Shield Properties
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health", meta = (ClampMin = "0.0"))
    double MaxHealth = 100.0;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Health", meta = (ClampMin = "0.0"))
    double CurrentHealth = 100.0;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Shield", meta = (ClampMin = "0.0"))
    double MaxShield = 50.0;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Shield", meta = (ClampMin = "0.0"))
    double CurrentShield = 50.0;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Armor", meta = (ClampMin = "0.0", ClampMax = "100.0"))
    double ArmorPercentage = 25.0;

public:
    // Main damage function - equivalent to PlayerTakesDamage custom event
    UFUNCTION(BlueprintCallable, Category = "Health")
    void TakeDamage(double Damage);

    // Getters for current values
    UFUNCTION(BlueprintPure, Category = "Health")
    FORCEINLINE double GetCurrentHealth() const { return CurrentHealth; }

    UFUNCTION(BlueprintPure, Category = "Health")
    FORCEINLINE double GetMaxHealth() const { return MaxHealth; }

    UFUNCTION(BlueprintPure, Category = "Shield")
    FORCEINLINE double GetCurrentShield() const { return CurrentShield; }

    UFUNCTION(BlueprintPure, Category = "Shield")
    FORCEINLINE double GetMaxShield() const { return MaxShield; }

    UFUNCTION(BlueprintPure, Category = "Armor")
    FORCEINLINE double GetArmorPercentage() const { return ArmorPercentage; }

    // Health percentage for UI
    UFUNCTION(BlueprintPure, Category = "Health")
    double GetHealthPercentage() const;

    // Shield percentage for UI
    UFUNCTION(BlueprintPure, Category = "Shield")
    double GetShieldPercentage() const;

    // Check if actor is alive
    UFUNCTION(BlueprintPure, Category = "Health")
    FORCEINLINE bool IsAlive() const { return CurrentHealth > 0.0; }

    // Event delegates for other systems to bind to
    UPROPERTY(BlueprintAssignable, Category = "Health Events")
    FOnHealthChanged OnHealthChanged;

    UPROPERTY(BlueprintAssignable, Category = "Health Events")
    FOnShieldChanged OnShieldChanged;

    UPROPERTY(BlueprintAssignable, Category = "Health Events")
    FOnDeath OnDeath;

private:
    // Helper function to calculate armor-reduced damage
    FORCEINLINE double CalculateArmorReducedDamage(double IncomingDamage) const
    {
       return IncomingDamage * (1.0 - (ArmorPercentage / 100.0));
    }

    // Helper function to handle death
    void HandleDeath();

    // Helper function to broadcast health change
    void BroadcastHealthChanged();

    // Helper function to broadcast shield change
    void BroadcastShieldChanged();
};

CPP File

#include "HealthComponent.h"
#include "Engine/Engine.h"
#include "GameFramework/Actor.h"

UHealthComponent::UHealthComponent()
{
    // Set this component to be ticked every frame (can be disabled if not needed)
    PrimaryComponentTick.bCanEverTick = false;
}

void UHealthComponent::TakeDamage(double Damage)
{
    // Early exit if no damage or already dead
    if (Damage <= 0.0 || CurrentHealth <= 0.0)
    {
       return;
    }

    // Store previous values for event comparison
    const double PreviousHealth = CurrentHealth;
    const double PreviousShield = CurrentShield;

    // Follow exact Blueprint logic
    if (CurrentShield > 0.0)
    {
       // Calculate shield damage with armor reduction
       const double ShieldDamage = CalculateArmorReducedDamage(Damage);
       
       // Calculate remaining damage after shield absorption
       const double RemainingDamage = FMath::Max(ShieldDamage - CurrentShield, 0.0);
       
       // Update shield (clamp to 0 minimum)
       CurrentShield = FMath::Max(CurrentShield - ShieldDamage, 0.0);
       
       // Broadcast shield change if it actually changed
       if (CurrentShield != PreviousShield)
       {
          BroadcastShieldChanged();
       }

       if (RemainingDamage > 0.0)
       {
          // Apply remaining damage to health
          CurrentHealth = CurrentHealth - RemainingDamage;
          
          // Broadcast health change
          BroadcastHealthChanged();
          
          if (CurrentHealth <= 0.0)
          {
             // Handle death
             HandleDeath();
          }
          else
          {
             // Log health for debugging (equivalent to Blueprint's PrintString)
             UE_LOG(LogTemp, Log, TEXT("Health: %f"), CurrentHealth);
          }
       }
       else
       {
          // Shields absorbed all damage (equivalent to Blueprint's PrintString)
          UE_LOG(LogTemp, Log, TEXT("Shields absorbed all damage"));
       }
    }
    else
    {
       // No shield - apply armor-reduced damage directly to health
       const double ReducedDamage = CalculateArmorReducedDamage(Damage);
       CurrentHealth = CurrentHealth - ReducedDamage;
       
       // Broadcast health change
       BroadcastHealthChanged();
       
       if (CurrentHealth <= 0.0)
       {
          // Handle death
          HandleDeath();
       }
       else
       {
          // Log health for debugging (equivalent to Blueprint's PrintString)
          UE_LOG(LogTemp, Log, TEXT("Health: %f"), CurrentHealth);
       }
    }
}

double UHealthComponent::GetHealthPercentage() const
{
    return MaxHealth > 0.0 ? (CurrentHealth / MaxHealth) : 0.0;
}

double UHealthComponent::GetShieldPercentage() const
{
    return MaxShield > 0.0 ? (CurrentShield / MaxShield) : 0.0;
}

void UHealthComponent::HandleDeath()
{
    // Ensure health is exactly 0
    CurrentHealth = 0.0;
    
    // Broadcast death event first
    OnDeath.Broadcast();
    
    // Broadcast final health change
    BroadcastHealthChanged();
    
    // Destroy the owner actor (equivalent to K2_DestroyActor in Blueprint)
    if (AActor* Owner = GetOwner())
    {
       Owner->Destroy();
    }
}

void UHealthComponent::BroadcastHealthChanged()
{
    OnHealthChanged.Broadcast(CurrentHealth);
}

void UHealthComponent::BroadcastShieldChanged()
{
    OnShieldChanged.Broadcast(CurrentShield);
}

C++ Refactoring Comparison

Criteria Gemini Pro App ChatGPT Free Claude 4 Sonnet
Translation Accuracy β˜…β˜…β˜…β˜…β˜† (4/5) β˜…β˜…β˜…β˜†β˜† (3/5) β˜…β˜…β˜…β˜…β˜… (5/5)
Code Structure β˜…β˜…β˜…β˜…β˜† (4/5) β˜…β˜…β˜…β˜†β˜† (3/5) β˜…β˜…β˜…β˜…β˜… (5/5)
Error Handling β˜…β˜…β˜…β˜…β˜† (4/5) β˜…β˜…β˜…β˜†β˜† (3/5) β˜…β˜…β˜…β˜…β˜… (5/5)
UE5 Conventions β˜…β˜…β˜…β˜…β˜† (4/5) β˜…β˜…β˜…β˜…β˜† (4/5) β˜…β˜…β˜…β˜…β˜… (5/5)
Documentation β˜…β˜…β˜…β˜…β˜† (4/5) β˜…β˜…β˜…β˜†β˜† (3/5) β˜…β˜…β˜…β˜…β˜… (5/5)
Extensibility β˜…β˜…β˜…β˜…β˜† (4/5) β˜…β˜…β˜…β˜†β˜† (3/5) β˜…β˜…β˜…β˜…β˜… (5/5)
Completeness β˜…β˜…β˜…β˜…β˜† (4/5) β˜…β˜…β˜…β˜†β˜† (3/5) β˜…β˜…β˜…β˜…β˜… (5/5)
Performance β˜…β˜…β˜…β˜…β˜† (4/5) β˜…β˜…β˜…β˜†β˜† (3/5) β˜…β˜…β˜…β˜…β˜† (4/5)
TOTAL SCORE 32/40 25/40 39/40


πŸš€ Get Started

Ready to unlock AI analysis for your Blueprint workflows?

Join the beta testing program and experience professional Blueprint-to-AI translation.

 



Add comment

Comments

There are no comments yet.

Videos and Images Β©Epic Games / JSFILMS / tharlevfx / Peyton Varney