Make pickups pooled
This commit is contained in:
parent
c133ccd1e9
commit
f74ae1d263
BIN
Content/Enemy/DA_Enemy.uasset
(Stored with Git LFS)
BIN
Content/Enemy/DA_Enemy.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Gamemode/BP_DefaultGamemode.uasset
(Stored with Git LFS)
BIN
Content/Gamemode/BP_DefaultGamemode.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Pickups/EXP/BP_PickupTemplate.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Pickups/EXP/BP_PickupTemplate.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Pickups/EXP/DA_BlueEXPPickup.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Pickups/EXP/DA_BlueEXPPickup.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -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<UEXPComponent>())
|
||||
{
|
||||
expComponent->IncrementEXP(EXP);
|
||||
expComponent->IncrementEXP(PickupValue);
|
||||
Super::OnInnerBeginOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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<AEXPPickup>(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<AEXPPickup>(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()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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<UGoldComponent>())
|
||||
{
|
||||
goldComponent->IncrementGold(Gold);
|
||||
goldComponent->IncrementGold(PickupValue);
|
||||
Super::OnInnerBeginOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
7
Source/vampires/Interfaces/Pickupable.cpp
Normal file
7
Source/vampires/Interfaces/Pickupable.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
// Louis Hobbs | 2024-2025
|
||||
|
||||
|
||||
#include "Pickupable.h"
|
||||
|
||||
|
||||
// Add default functionality here for any IPickupable functions that are not pure virtual.
|
31
Source/vampires/Interfaces/Pickupable.h
Normal file
31
Source/vampires/Interfaces/Pickupable.h
Normal file
@ -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();
|
||||
};
|
@ -28,4 +28,7 @@ public:
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
AObjectPoolManager* GetProjectileObjectPoolManager();
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
AObjectPoolManager* GetPickupObjectPoolManager();
|
||||
};
|
||||
|
@ -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<UCurveBase*> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<UPickupDataAsset> 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<UTimelineComponent> TimelineComponent;
|
||||
TObjectPtr<UTimelineComponent> 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,
|
||||
|
@ -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<UPaperSprite> WeaponSprite = nullptr;
|
||||
TObjectPtr<UPaperSprite> PickupSprite = nullptr;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Pickup Properties")
|
||||
TObjectPtr<USoundBase> PickupSoundBase = nullptr;
|
||||
|
@ -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<AObjectPoolManager>();
|
||||
TSubclassOf<AActor> pickupTemplate = PickupTemplate;
|
||||
PickupObjectPoolManager->InitializeObjectPool(pickupTemplate);
|
||||
}
|
||||
|
||||
return PickupObjectPoolManager;
|
||||
}
|
||||
|
||||
void AVampireGameMode::IncrementEnemyDeathCount()
|
||||
{
|
||||
EnemyDeathCount++;
|
||||
|
@ -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<AProjectile> ProjectileTemplate;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
TSubclassOf<AEXPPickup> PickupTemplate;
|
||||
|
||||
FOnEnemyDeathCountIncrementDelegate OnEnemyDeathCountIncrementDelegate;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
@ -47,6 +51,8 @@ private:
|
||||
|
||||
TObjectPtr<AObjectPoolManager> ProjectileObjectPoolManager = nullptr;
|
||||
|
||||
TObjectPtr<AObjectPoolManager> 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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user