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.
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.
Videos and Images Β©Epic Games / JSFILMS / tharlevfx / Peyton Varney
Add comment
Comments