From f74ae1d2639803712240de03bba31d55d1028d44 Mon Sep 17 00:00:00 2001 From: baz Date: Sun, 16 Feb 2025 22:29:37 +0000 Subject: [PATCH] Make pickups pooled --- Content/Enemy/DA_Enemy.uasset | 4 +- Content/Gamemode/BP_DefaultGamemode.uasset | 4 +- Content/Pickups/EXP/BP_PickupTemplate.uasset | 3 ++ Content/Pickups/EXP/DA_BlueEXPPickup.uasset | 3 ++ Source/vampires/EXPPickup.cpp | 7 +-- Source/vampires/EXPPickup.h | 7 --- Source/vampires/EnemyCharacter.cpp | 41 +++++++++++----- Source/vampires/EnemyCharacter.h | 3 ++ Source/vampires/EnemyDataAsset.h | 4 ++ Source/vampires/GoldPickup.cpp | 7 +-- Source/vampires/GoldPickup.h | 7 --- Source/vampires/Interfaces/Pickupable.cpp | 7 +++ Source/vampires/Interfaces/Pickupable.h | 31 ++++++++++++ Source/vampires/Interfaces/Pools.h | 3 ++ Source/vampires/Pickup.cpp | 51 +++++++++++++++++++- Source/vampires/Pickup.h | 20 ++++---- Source/vampires/PickupDataAsset.h | 9 +--- Source/vampires/VampireGameMode.cpp | 14 ++++++ Source/vampires/VampireGameMode.h | 8 +++ 19 files changed, 174 insertions(+), 59 deletions(-) create mode 100644 Content/Pickups/EXP/BP_PickupTemplate.uasset create mode 100644 Content/Pickups/EXP/DA_BlueEXPPickup.uasset create mode 100644 Source/vampires/Interfaces/Pickupable.cpp create mode 100644 Source/vampires/Interfaces/Pickupable.h diff --git a/Content/Enemy/DA_Enemy.uasset b/Content/Enemy/DA_Enemy.uasset index 5745339..83c590e 100644 --- a/Content/Enemy/DA_Enemy.uasset +++ b/Content/Enemy/DA_Enemy.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4a746fd5a4be7c290faf668c97e316529f7beff79d228252f75bfae39af1fc57 -size 1764 +oid sha256:721f8d953e1222897adc59f4c062c636254840cab1839c7da2f7bb8bdb68f4c3 +size 1965 diff --git a/Content/Gamemode/BP_DefaultGamemode.uasset b/Content/Gamemode/BP_DefaultGamemode.uasset index 3b69536..61822c0 100644 --- a/Content/Gamemode/BP_DefaultGamemode.uasset +++ b/Content/Gamemode/BP_DefaultGamemode.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7914a67317c8e03d9a2ba74fb2d1f640eb4ae9620e196003d4977e42eb7770b -size 21755 +oid sha256:687c80b754c3098ddedbf2fec50a312a28c7f3b1813ba52f5ba7a2773e330da4 +size 21959 diff --git a/Content/Pickups/EXP/BP_PickupTemplate.uasset b/Content/Pickups/EXP/BP_PickupTemplate.uasset new file mode 100644 index 0000000..ebee1b5 --- /dev/null +++ b/Content/Pickups/EXP/BP_PickupTemplate.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08ccd14cf99ce60e7838e3a5ce6b7ebb879b2b17789301705b653c7e2f454cba +size 24435 diff --git a/Content/Pickups/EXP/DA_BlueEXPPickup.uasset b/Content/Pickups/EXP/DA_BlueEXPPickup.uasset new file mode 100644 index 0000000..c42d877 --- /dev/null +++ b/Content/Pickups/EXP/DA_BlueEXPPickup.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2fcdaa7edbd58b15160ca419b9eba5587ac03d13bab804f0bc97757dab7bcbe +size 2047 diff --git a/Source/vampires/EXPPickup.cpp b/Source/vampires/EXPPickup.cpp index 8112541..ef13568 100644 --- a/Source/vampires/EXPPickup.cpp +++ b/Source/vampires/EXPPickup.cpp @@ -9,18 +9,13 @@ void AEXPPickup::BeginPlay() Super::BeginPlay(); } -void AEXPPickup::Tick(float DeltaSeconds) -{ - Super::Tick(DeltaSeconds); -} - void AEXPPickup::OnInnerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) { if (UEXPComponent* expComponent = OtherActor->GetComponentByClass()) { - expComponent->IncrementEXP(EXP); + expComponent->IncrementEXP(PickupValue); Super::OnInnerBeginOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult); } } diff --git a/Source/vampires/EXPPickup.h b/Source/vampires/EXPPickup.h index 002b702..3424192 100644 --- a/Source/vampires/EXPPickup.h +++ b/Source/vampires/EXPPickup.h @@ -14,17 +14,10 @@ class VAMPIRES_API AEXPPickup : public APickup { GENERATED_BODY() -public: - - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Pickup") - int EXP = 1; - protected: virtual void BeginPlay() override; public: - virtual void Tick(float DeltaSeconds) override; - virtual void OnInnerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override; diff --git a/Source/vampires/EnemyCharacter.cpp b/Source/vampires/EnemyCharacter.cpp index 10b1213..1788946 100644 --- a/Source/vampires/EnemyCharacter.cpp +++ b/Source/vampires/EnemyCharacter.cpp @@ -45,34 +45,53 @@ void AEnemyCharacter::OnDamaged(FDamageInfo damageInfo) void AEnemyCharacter::OnDeath(FDamageInfo damageInfo) { // TODO: Replace pickup spawning with pooling - FActorSpawnParameters actorSpawnParameters; - actorSpawnParameters.Owner = this; - actorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; - auto spawnLocation = GetActorLocation(); - spawnLocation.Z = 75.0f; + if (PickupTemplate) + { + AGameModeBase* gamemode = UGameplayStatics::GetGameMode(GetWorld()); - GetWorld()->SpawnActor(EXPPickupTemplate, spawnLocation, FRotator::ZeroRotator, - actorSpawnParameters); + if (UKismetSystemLibrary::DoesImplementInterface(gamemode, UPools::StaticClass())) + { + if (AObjectPoolManager* objectPoolManager = IPools::Execute_GetPickupObjectPoolManager(gamemode)) + { + AActor* pickup = objectPoolManager->GetObject(); + + if (UKismetSystemLibrary::DoesImplementInterface(pickup, UPickupable::StaticClass())) + { + IPickupable::Execute_LoadDataFromDataAsset(pickup, PickupTemplate); + pickup->SetActorLocation(GetActorLocation()); + } + } + } + } + + + // FActorSpawnParameters actorSpawnParameters; + // actorSpawnParameters.Owner = this; + // actorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + // + // auto spawnLocation = GetActorLocation(); + // spawnLocation.Z = 75.0f; + // + // GetWorld()->SpawnActor(EXPPickupTemplate, spawnLocation, FRotator::ZeroRotator, + // actorSpawnParameters); } void AEnemyCharacter::LoadDataFromDataAsset_Implementation(UEnemyDataAsset* enemyDataAsset) { if (enemyDataAsset != nullptr) { - // TODO: Load more data StaticMeshComponent->SetStaticMesh(enemyDataAsset->StaticMesh); - BehaviorTree = enemyDataAsset->BehaviorTree; + PickupTemplate = enemyDataAsset->PickupDataAsset; } } void AEnemyCharacter::ResetData_Implementation() { - // TODO: Reset more data StaticMeshComponent->SetStaticMesh(nullptr); - BehaviorTree = nullptr; + PickupTemplate = nullptr; } float AEnemyCharacter::GetCapsuleRadius_Implementation() diff --git a/Source/vampires/EnemyCharacter.h b/Source/vampires/EnemyCharacter.h index 08aaad6..e60f4f7 100644 --- a/Source/vampires/EnemyCharacter.h +++ b/Source/vampires/EnemyCharacter.h @@ -3,6 +3,7 @@ #pragma once #include "CoreMinimal.h" +#include "PickupDataAsset.h" #include "VampireCharacter.h" #include "Interfaces/Enemyable.h" #include "EnemyCharacter.generated.h" @@ -28,6 +29,8 @@ private: UObjectPoolComponent* ObjectPoolComponent = nullptr; + UPickupDataAsset* PickupTemplate = nullptr; + public: AEnemyCharacter(const FObjectInitializer& ObjectInitializer); diff --git a/Source/vampires/EnemyDataAsset.h b/Source/vampires/EnemyDataAsset.h index df8b325..c10ccf5 100644 --- a/Source/vampires/EnemyDataAsset.h +++ b/Source/vampires/EnemyDataAsset.h @@ -3,6 +3,7 @@ #pragma once #include "CoreMinimal.h" +#include "PickupDataAsset.h" #include "Engine/DataAsset.h" #include "EnemyDataAsset.generated.h" @@ -23,4 +24,7 @@ public: UPROPERTY(EditDefaultsOnly, Meta = (AllowPrivateAccess = "true")) UBehaviorTree* BehaviorTree = nullptr; + + UPROPERTY(EditDefaultsOnly, Meta = (AllowPrivateAccess = "true")) + UPickupDataAsset* PickupDataAsset = nullptr; }; diff --git a/Source/vampires/GoldPickup.cpp b/Source/vampires/GoldPickup.cpp index 11fec0c..0ac112d 100644 --- a/Source/vampires/GoldPickup.cpp +++ b/Source/vampires/GoldPickup.cpp @@ -12,18 +12,13 @@ void AGoldPickup::BeginPlay() Super::BeginPlay(); } -void AGoldPickup::Tick(float DeltaSeconds) -{ - Super::Tick(DeltaSeconds); -} - void AGoldPickup::OnInnerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) { if (UGoldComponent* goldComponent = OtherActor->GetComponentByClass()) { - goldComponent->IncrementGold(Gold); + goldComponent->IncrementGold(PickupValue); Super::OnInnerBeginOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult); } } diff --git a/Source/vampires/GoldPickup.h b/Source/vampires/GoldPickup.h index 327f6c2..1572b18 100644 --- a/Source/vampires/GoldPickup.h +++ b/Source/vampires/GoldPickup.h @@ -13,18 +13,11 @@ UCLASS() class VAMPIRES_API AGoldPickup : public APickup { GENERATED_BODY() - -public: - - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) - int Gold = 1; protected: virtual void BeginPlay() override; public: - virtual void Tick(float DeltaSeconds) override; - virtual void OnInnerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override; diff --git a/Source/vampires/Interfaces/Pickupable.cpp b/Source/vampires/Interfaces/Pickupable.cpp new file mode 100644 index 0000000..8be25c2 --- /dev/null +++ b/Source/vampires/Interfaces/Pickupable.cpp @@ -0,0 +1,7 @@ +// Louis Hobbs | 2024-2025 + + +#include "Pickupable.h" + + +// Add default functionality here for any IPickupable functions that are not pure virtual. diff --git a/Source/vampires/Interfaces/Pickupable.h b/Source/vampires/Interfaces/Pickupable.h new file mode 100644 index 0000000..8a1bd28 --- /dev/null +++ b/Source/vampires/Interfaces/Pickupable.h @@ -0,0 +1,31 @@ +// Louis Hobbs | 2024-2025 + +#pragma once + +#include "CoreMinimal.h" +#include "UObject/Interface.h" +#include "Pickupable.generated.h" + +class UPickupDataAsset; +// This class does not need to be modified. +UINTERFACE() +class UPickupable : public UInterface +{ + GENERATED_BODY() +}; + +/** + * + */ +class VAMPIRES_API IPickupable +{ + GENERATED_BODY() + + // Add interface functions to this class. This is the class that will be inherited to implement this interface. +public: + UFUNCTION(BlueprintNativeEvent) + void LoadDataFromDataAsset(UPickupDataAsset* PickupDataAsset); + + UFUNCTION(BlueprintNativeEvent) + void ResetData(); +}; diff --git a/Source/vampires/Interfaces/Pools.h b/Source/vampires/Interfaces/Pools.h index 3b34901..882dcb6 100644 --- a/Source/vampires/Interfaces/Pools.h +++ b/Source/vampires/Interfaces/Pools.h @@ -28,4 +28,7 @@ public: UFUNCTION(BlueprintNativeEvent) AObjectPoolManager* GetProjectileObjectPoolManager(); + + UFUNCTION(BlueprintNativeEvent) + AObjectPoolManager* GetPickupObjectPoolManager(); }; diff --git a/Source/vampires/Pickup.cpp b/Source/vampires/Pickup.cpp index 84944f0..d0c66e6 100644 --- a/Source/vampires/Pickup.cpp +++ b/Source/vampires/Pickup.cpp @@ -2,10 +2,15 @@ #include "Pickup.h" + +#include "ObjectPoolManager.h" #include "PlayerCharacter.h" #include "Components/SphereComponent.h" #include "Kismet/GameplayStatics.h" #include "PaperSpriteComponent.h" +#include "PickupDataAsset.h" +#include "GameFramework/GameModeBase.h" +#include "Interfaces/Pools.h" // Sets default values APickup::APickup() @@ -54,6 +59,38 @@ void APickup::BeginPlay() } } +void APickup::LoadDataFromDataAsset_Implementation(UPickupDataAsset* PickupDataAsset) +{ + if (PickupDataAsset != nullptr) + { + PickupValue = PickupDataAsset->PickupValue; + SpriteComponent->SetSprite(PickupDataAsset->PickupSprite); + PickupSoundBase = PickupDataAsset->PickupSoundBase; + CurveFloat = PickupDataAsset->CurveFloat; + + if (CurveFloat != nullptr) + { + TimelineComponent->AddInterpFloat(CurveFloat, onTimelineCallback); + TimelineComponent->SetTimelineFinishedFunc(onTimelineFinishedCallback); + } + } +} + +void APickup::ResetData_Implementation() +{ + PickupValue = 0; + SpriteComponent->SetSprite(nullptr); + PickupSoundBase = nullptr; + CurveFloat = nullptr; + + TSet AllCurves; + TimelineComponent->GetAllCurves(AllCurves); + if (AllCurves.Num() > 0) + { + AllCurves.Reset(); + } +} + void APickup::OnInnerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) @@ -66,7 +103,19 @@ void APickup::OnInnerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AAct UGameplayStatics::PlaySound2D(GetWorld(), PickupSoundBase); } - Destroy(); + AGameModeBase* gamemode = UGameplayStatics::GetGameMode(GetWorld()); + if (UKismetSystemLibrary::DoesImplementInterface(gamemode, UPools::StaticClass())) + { + if (AObjectPoolManager* objectPoolManager = IPools::Execute_GetProjectileObjectPoolManager(gamemode)) + { + ResetData_Implementation(); + objectPoolManager->ReturnObject(this); + } + } + else + { + Destroy(); + } } } diff --git a/Source/vampires/Pickup.h b/Source/vampires/Pickup.h index 49a533c..ffe824d 100644 --- a/Source/vampires/Pickup.h +++ b/Source/vampires/Pickup.h @@ -5,6 +5,7 @@ #include "CoreMinimal.h" #include "Components/TimelineComponent.h" #include "GameFramework/Actor.h" +#include "Interfaces/Pickupable.h" #include "Pickup.generated.h" class UPickupDataAsset; @@ -13,26 +14,21 @@ class USphereComponent; class UPaperSpriteComponent; UCLASS() -class VAMPIRES_API APickup : public AActor +class VAMPIRES_API APickup : public AActor, public IPickupable { GENERATED_BODY() public: - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) - TObjectPtr PickupDataAsset; - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) - double PickupMovementRange = 500; - - UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) - double PickupMovementSpeed = 1000; - + int PickupValue = 1; + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) USphereComponent* InnerSphereComponent = nullptr; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) USphereComponent* OuterSphereComponent = nullptr; + // TODO: Replace with static mesh UPROPERTY(EditAnywhere) UPaperSpriteComponent* SpriteComponent = nullptr; @@ -40,7 +36,7 @@ public: USoundBase* PickupSoundBase = nullptr; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Timeline") - TObjectPtr TimelineComponent; + TObjectPtr TimelineComponent = nullptr; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Timeline") UCurveFloat* CurveFloat; @@ -58,7 +54,11 @@ public: protected: // Called when the game starts or when spawned virtual void BeginPlay() override; + + virtual void LoadDataFromDataAsset_Implementation(UPickupDataAsset* PickupDataAsset) override; + virtual void ResetData_Implementation() override; + UFUNCTION() virtual void OnInnerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, diff --git a/Source/vampires/PickupDataAsset.h b/Source/vampires/PickupDataAsset.h index b579041..6e50503 100644 --- a/Source/vampires/PickupDataAsset.h +++ b/Source/vampires/PickupDataAsset.h @@ -20,14 +20,9 @@ public: UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") int PickupValue = 1; + // TODO: Replace with static mesh UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") - double PickupMovementRange = 500; - - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") - double PickupMovementSpeed = 1000; - - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") - TObjectPtr WeaponSprite = nullptr; + TObjectPtr PickupSprite = nullptr; UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties") TObjectPtr PickupSoundBase = nullptr; diff --git a/Source/vampires/VampireGameMode.cpp b/Source/vampires/VampireGameMode.cpp index fc01b96..bd04987 100644 --- a/Source/vampires/VampireGameMode.cpp +++ b/Source/vampires/VampireGameMode.cpp @@ -4,8 +4,10 @@ #include "VampireGameMode.h" #include "EnemyCharacter.h" +#include "EXPPickup.h" #include "HealthComponent.h" #include "ObjectPoolManager.h" +#include "Pickup.h" #include "PlayerCharacter.h" #include "Projectile.h" #include "VampirePlayerController.h" @@ -125,6 +127,18 @@ AObjectPoolManager* AVampireGameMode::GetProjectileObjectPoolManager_Implementat return ProjectileObjectPoolManager; } +AObjectPoolManager* AVampireGameMode::GetPickupObjectPoolManager_Implementation() +{ + if (PickupObjectPoolManager == nullptr) + { + PickupObjectPoolManager = GetWorld()->SpawnActor(); + TSubclassOf pickupTemplate = PickupTemplate; + PickupObjectPoolManager->InitializeObjectPool(pickupTemplate); + } + + return PickupObjectPoolManager; +} + void AVampireGameMode::IncrementEnemyDeathCount() { EnemyDeathCount++; diff --git a/Source/vampires/VampireGameMode.h b/Source/vampires/VampireGameMode.h index 038d292..3ae1237 100644 --- a/Source/vampires/VampireGameMode.h +++ b/Source/vampires/VampireGameMode.h @@ -8,6 +8,7 @@ #include "Interfaces/Pools.h" #include "VampireGameMode.generated.h" +class AEXPPickup; class UEnemyDataAsset; class AProjectile; class AObjectPoolManager; @@ -29,6 +30,9 @@ public: UPROPERTY(EditDefaultsOnly) TSubclassOf ProjectileTemplate; + UPROPERTY(EditDefaultsOnly) + TSubclassOf PickupTemplate; + FOnEnemyDeathCountIncrementDelegate OnEnemyDeathCountIncrementDelegate; UPROPERTY(EditDefaultsOnly) @@ -47,6 +51,8 @@ private: TObjectPtr ProjectileObjectPoolManager = nullptr; + TObjectPtr PickupObjectPoolManager = nullptr; + protected: virtual void BeginPlay() override; @@ -64,6 +70,8 @@ public: virtual AObjectPoolManager* GetProjectileObjectPoolManager_Implementation() override; + virtual AObjectPoolManager* GetPickupObjectPoolManager_Implementation() override; + protected: UFUNCTION() void SpawnEnemy();