mirror of
https://github.com/kuhyx/praca_magisterska.git
synced 2026-07-04 14:43:07 +02:00
17 KiB
17 KiB
Appendix D: Complete C++ Class Reference
← Part 9: Final Setup | Back to Index | Code-First Approach →
Overview
This appendix provides complete, copy-paste ready C++ implementations for all game classes. These can be used instead of the Blueprint-heavy tutorial to create the same bullet-hell game with:
- ✅ Faster development - copy entire variable blocks instead of clicking UI
- ✅ Better version control - readable Git diffs instead of binary Blueprint files
- ✅ Easier refactoring - IDE tools for rename, find references, etc.
- ✅ Compile-time safety - catch type errors before runtime
File Structure
Add these files to your Unreal C++ project:
Source/BulletHellGame/
├── BulletHellGame.Build.cs # (already exists)
├── BulletHellGame.h # (already exists)
├── STGPawn.h # Player ship
├── STGPawn.cpp
├── STGProjectile.h # Bullets
├── STGProjectile.cpp
├── STGEnemy.h # Enemy ships
├── STGEnemy.cpp
├── STGGameMode.h # Game rules, spawning
├── STGGameMode.cpp
└── STGHUD.h # UI overlay
└── STGHUD.cpp
Complete Variable Lists (Copy-Paste Ready!)
BP_Player Variables (Now in STGPawn.h)
Instead of manually creating 12 variables in Blueprint UI, copy this block:
// In STGPawn.h, inside the class definition:
// ===== MOVEMENT & BOUNDARIES =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float MoveSpeed = 750.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
FVector2D BoundsMin = FVector2D(-850.0f, -450.0f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
FVector2D BoundsMax = FVector2D(850.0f, 450.0f);
// ===== FIRING =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float FireInterval = 0.08f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float BulletSpeed = 2200.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 VolleySize = 3;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float VolleySpread = 12.0f;
// ===== LIVES & SCORE =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 MaxLives = 3;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
int32 CurrentLives = 3;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
int32 Score = 0;
// ===== SPECIAL ABILITY =====
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
bool bSpecialUsed = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float FireRate = 0.08f;
Time saved: 15 minutes of clicking vs 30 seconds of copy-paste!
BP_Enemy Variables (Now in STGEnemy.h)
// In STGEnemy.h, inside the class definition:
// ===== HEALTH & SCORE =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 MaxHealth = 12;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
int32 CurrentHealth = 12;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 ScoreValue = 50;
// ===== MOVEMENT =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float VerticalSpeed = 220.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float HorizontalAmplitude = 250.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float HorizontalFrequency = 1.8f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float DespawnY = -750.0f;
// ===== FIRING =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float FireInterval = 0.35f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 BulletsPerBurst = 20;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float BurstSpread = 360.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float EnemyBulletSpeed = 1000.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float EnemyBulletLifetime = 6.0f;
Time saved: 20 minutes of clicking vs 30 seconds of copy-paste!
BP_Bullet Variables (Now in STGProjectile.h)
// In STGProjectile.h, inside the class definition:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
bool bIsPlayerBullet = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
float Damage = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
FLinearColor BulletColor = FLinearColor::Green;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
float Lifetime = 4.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
float Speed = 1200.0f;
BP_GameMode Variables (Now in STGGameMode.h)
// In STGGameMode.h, inside the class definition:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Game Rules")
float GameDuration = 300.0f; // 5 minutes (300 seconds)
UPROPERTY(BlueprintReadOnly, Category = "Game Rules")
float TimeRemaining = 300.0f;
UPROPERTY(BlueprintReadOnly, Category = "Game Rules")
bool bIsGameOver = false;
UPROPERTY(BlueprintReadOnly, Category = "Game Rules")
bool bIsVictory = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
float BaseSpawnRate = 2.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
float SpawnAreaHalfWidth = 900.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
int32 MaxSimultaneousEnemies = 120;
STGPawn.h (Complete File)
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "STGPawn.generated.h"
class UCameraComponent;
class USpringArmComponent;
class UStaticMeshComponent;
class UBoxComponent;
UCLASS()
class BULLETHELLGAME_API ASTGPawn : public APawn
{
GENERATED_BODY()
public:
ASTGPawn();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// ===== COMPONENTS =====
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UStaticMeshComponent* ShipMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
USpringArmComponent* SpringArm;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UCameraComponent* Camera;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UBoxComponent* Hitbox;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UStaticMeshComponent* HitboxIndicator;
// ===== MOVEMENT & BOUNDARIES =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float MoveSpeed = 750.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
FVector2D BoundsMin = FVector2D(-850.0f, -450.0f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
FVector2D BoundsMax = FVector2D(850.0f, 450.0f);
// ===== FIRING =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float FireInterval = 0.08f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float BulletSpeed = 2200.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 VolleySize = 3;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float VolleySpread = 12.0f;
// ===== LIVES & SCORE =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 MaxLives = 3;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
int32 CurrentLives = 3;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
int32 Score = 0;
// ===== SPECIAL ABILITY =====
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
bool bSpecialUsed = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float FireRate = 0.08f;
// ===== INPUT FUNCTIONS =====
void MoveForward(float Value);
void MoveRight(float Value);
void StartFire();
void StopFire();
void UseSpecial();
// ===== GAME LOGIC =====
void FireShot();
void TakeHit(int32 Damage);
void HandleDeath();
void AddScore(int32 Points);
private:
FTimerHandle TimerHandle_Fire;
bool bIsFiring = false;
FVector MovementInput;
float FireTimer = 0.0f;
};
STGProjectile.h (Complete File)
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "STGProjectile.generated.h"
class USphereComponent;
class UProjectileMovementComponent;
class UStaticMeshComponent;
UCLASS()
class BULLETHELLGAME_API ASTGProjectile : public AActor
{
GENERATED_BODY()
public:
ASTGProjectile();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
// Components
UPROPERTY(VisibleDefaultsOnly, Category=Projectile)
USphereComponent* CollisionComp;
UPROPERTY(VisibleDefaultsOnly, Category=Projectile)
UStaticMeshComponent* MeshComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Movement)
UProjectileMovementComponent* ProjectileMovement;
// Variables
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
bool bIsPlayerBullet = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
float Damage = 1.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
FLinearColor BulletColor = FLinearColor::Green;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Gameplay")
float Lifetime = 4.0f;
// Functions
UFUNCTION()
void OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
void SetBulletColor(FLinearColor InColor);
void SetSpeed(float InSpeed);
private:
UMaterialInstanceDynamic* DynamicMaterial;
};
STGEnemy.h (Complete File)
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "STGEnemy.generated.h"
UCLASS()
class BULLETHELLGAME_API ASTGEnemy : public AActor
{
GENERATED_BODY()
public:
ASTGEnemy();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
// Components
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
class UStaticMeshComponent* MeshComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
class UBoxComponent* CollisionComp;
// ===== HEALTH & SCORE =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 MaxHealth = 12;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
int32 CurrentHealth = 12;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 ScoreValue = 50;
// ===== MOVEMENT =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float VerticalSpeed = 220.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float HorizontalAmplitude = 250.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float HorizontalFrequency = 1.8f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float DespawnY = -750.0f;
// ===== FIRING =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float FireInterval = 0.35f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
int32 BulletsPerBurst = 20;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float BurstSpread = 360.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float EnemyBulletSpeed = 1000.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float EnemyBulletLifetime = 6.0f;
// Functions
void Fire();
void HandleDamage(float DamageAmount);
UFUNCTION()
void OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
private:
FTimerHandle TimerHandle_Fire;
float BaseX = 0.0f;
float WaveSeed = 0.0f;
UMaterialInstanceDynamic* DynamicMaterial;
};
STGGameMode.h (Complete File)
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "STGGameMode.generated.h"
UCLASS()
class BULLETHELLGAME_API ASTGGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
ASTGGameMode();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
// ===== GAME RULES =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Game Rules")
float GameDuration = 300.0f; // 5 minutes
UPROPERTY(BlueprintReadOnly, Category = "Game Rules")
float TimeRemaining = 300.0f;
UPROPERTY(BlueprintReadOnly, Category = "Game Rules")
bool bIsGameOver = false;
UPROPERTY(BlueprintReadOnly, Category = "Game Rules")
bool bIsVictory = false;
UPROPERTY(BlueprintReadOnly, Category = "Game Rules")
bool bTimerEnded = false;
// ===== SPAWNING =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
float BaseSpawnRate = 2.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
float SpawnAreaHalfWidth = 900.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Spawning")
int32 MaxSimultaneousEnemies = 120;
// Functions
void SpawnEnemy();
void GameOver();
void Victory();
void OnEnemyKilled();
void OnPlayerDied();
FVector GetSpawnLocation();
private:
FTimerHandle TimerHandle_Spawn;
float SpawnRate = 2.0f;
int32 TotalEnemiesSpawned = 0;
int32 TotalEnemiesKilled = 0;
void UpdateDifficulty();
float DifficultyMultiplier = 1.0f;
};
UPROPERTY Macros Explained
Common Patterns
// Editable in editor, visible in Blueprints, with default value
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float MoveSpeed = 750.0f;
// Read-only in editor and Blueprints
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats")
int32 CurrentLives = 3;
// Only visible in editor Details panel, not exposed to Blueprints
UPROPERTY(VisibleDefaultsOnly, Category = "Components")
UStaticMeshComponent* MeshComp;
// Editable only on archetype (Blueprint class defaults), not instances
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Config")
float FireRate = 0.08f;
Specifier Reference
| Specifier | Meaning |
|---|---|
EditAnywhere |
Can edit value in Details panel (both class defaults and instances) |
EditDefaultsOnly |
Can edit only in class defaults (Blueprint), not placed instances |
VisibleAnywhere |
Shows value in Details panel but cannot edit |
BlueprintReadWrite |
Can Get/Set in Blueprints |
BlueprintReadOnly |
Can Get (but not Set) in Blueprints |
Category = "Name" |
Groups properties in Details panel |
Benefits Summary
Code-First C++ Approach
Advantages:
- ✅ 90% faster variable setup - copy-paste blocks vs clicking UI
- ✅ Version control friendly - readable Git diffs
- ✅ Refactoring tools - IDE rename, find references, code navigation
- ✅ Type safety - compiler catches errors before runtime
- ✅ Documentation - code comments in same file as logic
- ✅ Batch operations - change multiple values with find/replace
- ✅ Code reuse - inherit classes, template patterns
Disadvantages:
- ❌ Longer initial compile time (~30-60 seconds vs instant Blueprint)
- ❌ Requires C++ knowledge
- ❌ Need to recompile after changes (though hot reload helps)
When to Use Each
| Task | Use C++ | Use Blueprint |
|---|---|---|
| Define game variables | ✅ Yes | ❌ No (too slow) |
| Implement game logic | ✅ Yes | ❌ No (hard to maintain) |
| Assign visual assets | ❌ No | ✅ Yes (easier in UI) |
| Create materials | ❌ No | ✅ Yes (visual editor) |
| Animation state machines | ❌ No | ✅ Yes (timeline editor) |
| Level design | ❌ No | ✅ Yes (visual placement) |
Recommended Hybrid:
- Create C++ base classes with all logic and variables
- Create Blueprint child classes that inherit from C++
- Use Blueprints only to set visual assets (meshes, materials, sounds)
Migration Guide
If You Started with Blueprint Tutorial
To migrate existing Blueprint variables to C++:
- Open your Blueprint (e.g.,
BP_Player) - Copy all variable names and values to a text file
- Create C++ header file (e.g.,
STGPawn.h) - Add UPROPERTY declarations with copied names and default values
- Compile C++
- Reparent Blueprint:
- Open
BP_Player - File → Reparent Blueprint
- Select
STGPawn(your C++ class)
- Open
- Variables now come from C++!
- Delete old Blueprint variables (they're redundant)
Next Steps
- Complete Code-First Tutorial - Full implementation guide
- Blueprint Tutorial - Original Blueprint-heavy version
- Troubleshooting - Common issues
← Part 9: Final Setup | Back to Index | Code-First Approach →