Add Enemy Batching
This commit is contained in:
parent
2ad6b53ab3
commit
3a729caab0
|
@ -8,6 +8,7 @@
|
|||
|
||||
AEnemyCharacter::AEnemyCharacter(const FObjectInitializer& ObjectInitializer)
|
||||
{
|
||||
ObjectPoolComponent = CreateDefaultSubobject<UObjectPoolComponent>(TEXT("Object Pool Component"));
|
||||
}
|
||||
|
||||
void AEnemyCharacter::BeginPlay()
|
||||
|
@ -15,6 +16,8 @@ void AEnemyCharacter::BeginPlay()
|
|||
Super::BeginPlay();
|
||||
GetHealthComponent()->OnDamaged.BindUFunction(this, "OnDamaged");
|
||||
GetHealthComponent()->OnDeath.BindUFunction(this, "OnDeath");
|
||||
|
||||
ObjectPoolComponent->OnRetrieve.BindUFunction(this, "ResetHealth");
|
||||
}
|
||||
|
||||
void AEnemyCharacter::Tick(float DeltaTime)
|
||||
|
@ -33,17 +36,20 @@ void AEnemyCharacter::OnDamaged()
|
|||
|
||||
void AEnemyCharacter::OnDeath()
|
||||
{
|
||||
//if (IsValid(EXPPickupTemplate))
|
||||
//{
|
||||
FActorSpawnParameters actorSpawnParameters;
|
||||
actorSpawnParameters.Owner = this;
|
||||
actorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||
actorSpawnParameters.TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot;
|
||||
FActorSpawnParameters actorSpawnParameters;
|
||||
actorSpawnParameters.Owner = this;
|
||||
actorSpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||
actorSpawnParameters.TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot;
|
||||
|
||||
GetWorld()->SpawnActor<AEXPPickup>(EXPPickupTemplate, GetActorLocation(), FRotator::ZeroRotator,
|
||||
actorSpawnParameters);
|
||||
GetWorld()->SpawnActor<AEXPPickup>(EXPPickupTemplate, GetActorLocation(), FRotator::ZeroRotator,
|
||||
actorSpawnParameters);
|
||||
|
||||
AVampireGameMode* gamemode = Cast<AVampireGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
|
||||
gamemode->IncrementEnemyDeathCount();
|
||||
//}
|
||||
AVampireGameMode* gamemode = Cast<AVampireGameMode>(UGameplayStatics::GetGameMode(GetWorld()));
|
||||
gamemode->IncrementEnemyDeathCount();
|
||||
gamemode->GetEnemyObjectPoolManager()->ReturnObject(this);
|
||||
}
|
||||
|
||||
void AEnemyCharacter::ResetHealth()
|
||||
{
|
||||
GetHealthComponent()->ResetHealth();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "CoreMinimal.h"
|
||||
#include "EXPPickup.h"
|
||||
#include "ObjectPoolComponent.h"
|
||||
#include "VampireCharacter.h"
|
||||
#include "BehaviorTree/BehaviorTree.h"
|
||||
#include "EnemyCharacter.generated.h"
|
||||
|
@ -19,12 +20,13 @@ class VAMPIRES_API AEnemyCharacter : public AVampireCharacter
|
|||
public:
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
TSubclassOf<AEXPPickup> EXPPickupTemplate = nullptr;
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
UPROPERTY(EditDefaultsOnly, Meta = (AllowPrivateAccess = "true"))
|
||||
UBehaviorTree* BehaviorTree = nullptr;
|
||||
|
||||
|
||||
UObjectPoolComponent* ObjectPoolComponent = nullptr;
|
||||
|
||||
public:
|
||||
AEnemyCharacter(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
|
@ -41,4 +43,8 @@ public:
|
|||
|
||||
UFUNCTION()
|
||||
virtual void OnDeath();
|
||||
|
||||
private:
|
||||
UFUNCTION()
|
||||
void ResetHealth();
|
||||
};
|
||||
|
|
|
@ -70,6 +70,7 @@ void UHealthComponent::SetCurrentHealth(float value)
|
|||
void UHealthComponent::ResetHealth()
|
||||
{
|
||||
CurrentHealth = MaxHealth;
|
||||
IsDead = false;
|
||||
}
|
||||
|
||||
void UHealthComponent::RecoverHealth(float value)
|
||||
|
@ -105,4 +106,4 @@ void UHealthComponent::BeginPlay()
|
|||
Super::BeginPlay();
|
||||
|
||||
ResetHealth();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "ObjectPoolComponent.h"
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "ObjectPoolComponent.generated.h"
|
||||
|
||||
|
||||
DECLARE_DELEGATE(FOnRetrieve)
|
||||
DECLARE_DELEGATE(FOnReturn)
|
||||
|
||||
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||
class VAMPIRES_API UObjectPoolComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
FOnRetrieve OnRetrieve;
|
||||
FOnReturn OnReturn;
|
||||
};
|
|
@ -0,0 +1,69 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "ObjectPoolManager.h"
|
||||
|
||||
#include "ObjectPoolComponent.h"
|
||||
|
||||
// Called when the game starts or when spawned
|
||||
void AObjectPoolManager::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void AObjectPoolManager::InitializeObjectPool(TSubclassOf<AActor> Object, const int InitialObjectPoolSize)
|
||||
{
|
||||
for (int i = 0; i < InitialObjectPoolSize; i++)
|
||||
{
|
||||
AActor* object = GetWorld()->SpawnActor<AActor>(Object);
|
||||
SetObjectStatus(false, object);
|
||||
ObjectPool.Add(object);
|
||||
}
|
||||
}
|
||||
|
||||
void AObjectPoolManager::InitializeObjectPool(UClass* Object, int InitialObjectPoolSize)
|
||||
{
|
||||
for (int i = 0; i < InitialObjectPoolSize; i++)
|
||||
{
|
||||
AActor* object = GetWorld()->SpawnActor<AActor>(Object);
|
||||
SetObjectStatus(false, object);
|
||||
ObjectPool.Add(object);
|
||||
}
|
||||
}
|
||||
|
||||
AActor* AObjectPoolManager::GetObject()
|
||||
{
|
||||
for (AActor* object : ObjectPool)
|
||||
{
|
||||
if (object->IsHidden())
|
||||
{
|
||||
SetObjectStatus(true, object);
|
||||
|
||||
if (UObjectPoolComponent* objectPoolComponent = object->GetComponentByClass<UObjectPoolComponent>())
|
||||
{
|
||||
objectPoolComponent->OnRetrieve.ExecuteIfBound();
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AObjectPoolManager::ReturnObject(AActor* object)
|
||||
{
|
||||
SetObjectStatus(false, object);
|
||||
|
||||
if (UObjectPoolComponent* objectPoolComponent = object->GetComponentByClass<UObjectPoolComponent>())
|
||||
{
|
||||
objectPoolComponent->OnReturn.ExecuteIfBound();
|
||||
}
|
||||
}
|
||||
|
||||
void AObjectPoolManager::SetObjectStatus(bool enabled, AActor* object)
|
||||
{
|
||||
object->SetActorHiddenInGame(!enabled);
|
||||
object->SetActorTickEnabled(enabled);
|
||||
object->SetActorEnableCollision(enabled);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "ObjectPoolManager.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class VAMPIRES_API AObjectPoolManager : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
TArray<AActor*> ObjectPool = TArray<AActor*>();
|
||||
|
||||
public:
|
||||
void InitializeObjectPool(TSubclassOf<AActor> Object, int InitialObjectPoolSize = 400);
|
||||
void InitializeObjectPool(UClass* Object, int InitialObjectPoolSize = 400);
|
||||
|
||||
AActor* GetObject();
|
||||
|
||||
void ReturnObject(AActor* object);
|
||||
|
||||
protected:
|
||||
// Called when the game starts or when spawned
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
private:
|
||||
void SetObjectStatus(bool enabled, AActor* object);
|
||||
};
|
|
@ -61,7 +61,7 @@ void AVampireAIController::OnDeath(FDamageInfo info)
|
|||
{
|
||||
// TODO: Do stuff here
|
||||
EnemyCharacter->OnDeath();
|
||||
EnemyCharacter->DetachFromControllerPendingDestroy();
|
||||
/*EnemyCharacter->DetachFromControllerPendingDestroy();
|
||||
EnemyCharacter->GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
||||
EnemyCharacter->GetCapsuleComponent()->SetCollisionResponseToAllChannels(ECR_Ignore);
|
||||
|
||||
|
@ -72,7 +72,7 @@ void AVampireAIController::OnDeath(FDamageInfo info)
|
|||
characterMovementComponent->SetComponentTickEnabled(false);
|
||||
}
|
||||
GetWorldTimerManager().ClearTimer(PawnMoveToTimerHandle);
|
||||
EnemyCharacter->SetLifeSpan(0.1f);
|
||||
EnemyCharacter->SetLifeSpan(0.1f);*/
|
||||
}
|
||||
|
||||
void AVampireAIController::PawnMoveTo()
|
||||
|
|
|
@ -57,21 +57,37 @@ void AVampireGameMode::SpawnEnemy()
|
|||
UE_LOG(LogTemp, Warning, TEXT("Something broke"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
SpawnLocation.Z = PlayerCharacter->GetActorLocation().Z;
|
||||
FTransform Transform;
|
||||
Transform.SetLocation(SpawnLocation);
|
||||
|
||||
|
||||
FActorSpawnParameters SpawnParameters;
|
||||
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||
|
||||
AEnemyCharacter* Actor = GetWorld()->SpawnActor<AEnemyCharacter>(EnemyTemplate, Transform, SpawnParameters);
|
||||
float CapsuleRadius = Actor->GetCapsuleComponent()->GetScaledCapsuleRadius();
|
||||
FVector Direction = SpawnLocation - PlayerCharacter->GetActorLocation();
|
||||
Direction.Normalize();
|
||||
Direction *= CapsuleRadius;
|
||||
Actor->SetActorLocation(SpawnLocation + Direction);
|
||||
Actor->SpawnDefaultController();
|
||||
|
||||
if (AActor* object = GetEnemyObjectPoolManager()->GetObject())
|
||||
{
|
||||
AEnemyCharacter* Actor = Cast<AEnemyCharacter>(object);
|
||||
Actor->SetActorTransform(Transform);
|
||||
float CapsuleRadius = Actor->GetCapsuleComponent()->GetScaledCapsuleRadius();
|
||||
FVector Direction = SpawnLocation - PlayerCharacter->GetActorLocation();
|
||||
Direction.Normalize();
|
||||
Direction *= CapsuleRadius;
|
||||
Actor->SetActorLocation(SpawnLocation + Direction);
|
||||
Actor->SpawnDefaultController();
|
||||
}
|
||||
}
|
||||
|
||||
AObjectPoolManager* AVampireGameMode::GetEnemyObjectPoolManager()
|
||||
{
|
||||
if (EnemyObjectPoolManager == nullptr)
|
||||
{
|
||||
EnemyObjectPoolManager = GetWorld()->SpawnActor<AObjectPoolManager>();
|
||||
TSubclassOf<AActor> enemyTemplate = EnemyTemplate;
|
||||
EnemyObjectPoolManager->InitializeObjectPool(enemyTemplate);
|
||||
}
|
||||
|
||||
return EnemyObjectPoolManager;
|
||||
}
|
||||
|
||||
void AVampireGameMode::IncrementEnemyDeathCount()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "CoreMinimal.h"
|
||||
#include "EnemyCharacter.h"
|
||||
#include "ObjectPoolManager.h"
|
||||
#include "PlayerCharacter.h"
|
||||
#include "VampirePlayerController.h"
|
||||
#include "GameFramework/GameMode.h"
|
||||
|
@ -30,18 +31,21 @@ private:
|
|||
|
||||
int EnemyDeathCount = 0;
|
||||
|
||||
AObjectPoolManager* EnemyObjectPoolManager = nullptr;
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure)
|
||||
int GetEnemyDeathCount();
|
||||
|
||||
|
||||
UFUNCTION()
|
||||
void IncrementEnemyDeathCount();
|
||||
|
||||
AObjectPoolManager* GetEnemyObjectPoolManager();
|
||||
|
||||
protected:
|
||||
|
||||
UFUNCTION()
|
||||
void SpawnEnemy();
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue