Spawn enemies off map
This commit is contained in:
parent
770e33fce1
commit
7ba7379699
@ -94,7 +94,7 @@ DoubleClickTime=0.200000
|
||||
+ActionMappings=(ActionName="Shoot",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=LeftMouseButton)
|
||||
+ActionMappings=(ActionName="Shoot",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_RightTrigger)
|
||||
+ActionMappings=(ActionName="Boost",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=RightMouseButton)
|
||||
+ActionMappings=(ActionName="Boost",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_RightShoulder)
|
||||
+ActionMappings=(ActionName="Boost",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_LeftTrigger)
|
||||
+AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=W)
|
||||
+AxisMappings=(AxisName="MoveForward",Scale=-1.000000,Key=S)
|
||||
+AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=D)
|
||||
|
BIN
Content/EnemyMarker.uasset
Executable file
BIN
Content/EnemyMarker.uasset
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -9,7 +9,10 @@ AEnemySpawner::AEnemySpawner()
|
||||
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
|
||||
level_location = TUniquePtr<LevelLocation>(new LevelLocation());
|
||||
|
||||
spawn_delay_s = 5.0f;
|
||||
max_spawn_count = 5;
|
||||
}
|
||||
|
||||
// Called when the game starts or when spawned
|
||||
@ -27,6 +30,10 @@ void AEnemySpawner::BeginPlay()
|
||||
void AEnemySpawner::Tick(float delta_s)
|
||||
{
|
||||
Super::Tick(delta_s);
|
||||
if (!level_location->is_initialized())
|
||||
{
|
||||
level_location->initialize(GetWorld(), marker_class);
|
||||
}
|
||||
|
||||
spawn_wait_s += delta_s;
|
||||
if (next_spawn_threshold_s == 0)
|
||||
@ -35,23 +42,30 @@ void AEnemySpawner::Tick(float delta_s)
|
||||
}
|
||||
else if (spawn_wait_s > next_spawn_threshold_s)
|
||||
{
|
||||
FActorSpawnParameters spawnParameters;
|
||||
spawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||
spawnParameters.Owner = this;
|
||||
AAIController* controller = GetWorld()->SpawnActor<AAIController>(
|
||||
controller_class,
|
||||
GetActorLocation(),
|
||||
FRotator(0,0,0),
|
||||
spawnParameters
|
||||
);
|
||||
const int spawn_count = random.RandRange(0, max_spawn_count);
|
||||
|
||||
for (int i = 0; i < spawn_count; i++)
|
||||
{
|
||||
const FVector location = level_location->get_random_mark();
|
||||
FActorSpawnParameters spawnParameters;
|
||||
spawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||
spawnParameters.Owner = this;
|
||||
AAIController* controller = GetWorld()->SpawnActor<AAIController>(
|
||||
controller_class,
|
||||
location,
|
||||
FRotator(0,0,0),
|
||||
spawnParameters
|
||||
);
|
||||
|
||||
ABasePawn* enemy = GetWorld()->SpawnActor<ABasePawn>(
|
||||
pawn_class,
|
||||
location,
|
||||
FRotator(0,0,0),
|
||||
spawnParameters
|
||||
);
|
||||
controller->Possess(enemy);
|
||||
}
|
||||
|
||||
ABasePawn* enemy = GetWorld()->SpawnActor<ABasePawn>(
|
||||
pawn_class,
|
||||
GetActorLocation(),
|
||||
FRotator(0,0,0),
|
||||
spawnParameters
|
||||
);
|
||||
controller->Possess(enemy);
|
||||
spawn_wait_s = 0;
|
||||
next_spawn_threshold_s = spawn_delay_s + random.GetFraction();
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "BasePawn.h"
|
||||
#include "AIController.h"
|
||||
#include "LevelLocation.h"
|
||||
#include "EnemySpawner.generated.h"
|
||||
|
||||
UCLASS()
|
||||
@ -41,8 +42,25 @@ protected:
|
||||
UPROPERTY(EditAnywhere, Category = "Enemy")
|
||||
TSubclassOf<AAIController> controller_class;
|
||||
|
||||
/**
|
||||
* Enemy spawn location marker.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "Enemy")
|
||||
UClass* marker_class;
|
||||
|
||||
/**
|
||||
* Max number of enemies to spawn in one cycle.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "Enemy")
|
||||
int max_spawn_count;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Level location.
|
||||
*/
|
||||
TUniquePtr<LevelLocation> level_location;
|
||||
|
||||
/**
|
||||
* Random number stream.
|
||||
*/
|
||||
|
73
Source/PresidentsBrigade/LevelLocation.cpp
Executable file
73
Source/PresidentsBrigade/LevelLocation.cpp
Executable file
@ -0,0 +1,73 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "LevelLocation.h"
|
||||
#include "EngineUtils.h"
|
||||
#include "Util.h"
|
||||
|
||||
#define LogError(Msg) Util::log_error(TEXT("LevelLocation"), Msg)
|
||||
|
||||
LevelLocation::LevelLocation()
|
||||
{
|
||||
}
|
||||
|
||||
LevelLocation::~LevelLocation()
|
||||
{
|
||||
}
|
||||
|
||||
bool LevelLocation::is_initialized() const
|
||||
{
|
||||
return initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this class with a list of locations derived from the current world.
|
||||
*/
|
||||
void LevelLocation::initialize(UWorld *world, const UClass *marker_class)
|
||||
{
|
||||
initialized = true;
|
||||
|
||||
/*
|
||||
* Find all the markers in the world.
|
||||
*/
|
||||
for (TActorIterator<AActor> iterator(world); iterator; ++iterator)
|
||||
{
|
||||
AActor* actor = *iterator;
|
||||
if (actor)
|
||||
{
|
||||
UClass* actor_class = actor->GetClass();
|
||||
|
||||
if (actor_class == marker_class)
|
||||
{
|
||||
locations.Add(actor->GetActorLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (locations.Num() == 0)
|
||||
{
|
||||
LogError("No markers");
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize random stream.
|
||||
*/
|
||||
random.Initialize(FMath::Rand());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get world location of randomly selected mark.
|
||||
*
|
||||
* @return World location vector of mark.
|
||||
*/
|
||||
FVector LevelLocation::get_random_mark() const
|
||||
{
|
||||
if (locations.Num() == 0)
|
||||
{
|
||||
LogError("No markers");
|
||||
return FVector();
|
||||
}
|
||||
|
||||
const int index = random.RandRange(0, locations.Num() - 1);
|
||||
return locations[index];
|
||||
}
|
35
Source/PresidentsBrigade/LevelLocation.h
Executable file
35
Source/PresidentsBrigade/LevelLocation.h
Executable file
@ -0,0 +1,35 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class PRESIDENTSBRIGADE_API LevelLocation
|
||||
{
|
||||
public:
|
||||
LevelLocation();
|
||||
~LevelLocation();
|
||||
|
||||
void initialize(UWorld *world, const UClass *marker_class);
|
||||
FVector get_random_mark() const;
|
||||
bool is_initialized() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* True when initialized.
|
||||
*/
|
||||
bool initialized = false;
|
||||
|
||||
/**
|
||||
* Random number stream.
|
||||
*/
|
||||
FRandomStream random;
|
||||
|
||||
/**
|
||||
* List of locations.
|
||||
*/
|
||||
TArray<FVector> locations;
|
||||
};
|
@ -8,6 +8,11 @@
|
||||
#define LogInfo(Msg) Util::log_info(TEXT("APresidentAIController"), Msg)
|
||||
#define LogError(Msg) Util::log_error(TEXT("APresidentAIController"), Msg)
|
||||
|
||||
APresidentAIController::APresidentAIController()
|
||||
{
|
||||
level_location = TUniquePtr<LevelLocation>(new LevelLocation());
|
||||
}
|
||||
|
||||
void APresidentAIController::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
@ -31,7 +36,7 @@ void APresidentAIController::Tick(float delta)
|
||||
const FVector offset(1.0, 1.0, 0);
|
||||
starting_location = GetPawn()->GetActorLocation() + offset;
|
||||
target_location = starting_location;
|
||||
marker_locations = get_markers();
|
||||
level_location->initialize(GetWorld(), marker_class);
|
||||
|
||||
// Update state.
|
||||
current_state = state_t::idle;
|
||||
@ -47,7 +52,7 @@ void APresidentAIController::Tick(float delta)
|
||||
}
|
||||
else
|
||||
{
|
||||
target_location = is_home ? get_random_mark() : starting_location;
|
||||
target_location = is_home ? level_location->get_random_mark() : starting_location;
|
||||
MoveToLocation(target_location);
|
||||
current_state = state_t::moving;
|
||||
}
|
||||
@ -80,50 +85,3 @@ void APresidentAIController::OnMoveCompleted(FAIRequestID request_id, const FPat
|
||||
{
|
||||
move_completed = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to load all the markers in the level.
|
||||
*/
|
||||
TArray<FVector> APresidentAIController::get_markers() const
|
||||
{
|
||||
TArray<FVector> locations;
|
||||
for (TActorIterator<AActor> iterator(GetWorld()); iterator; ++iterator)
|
||||
{
|
||||
AActor* actor = *iterator;
|
||||
if (actor && actor != this)
|
||||
{
|
||||
UClass* actor_class = actor->GetClass();
|
||||
|
||||
if (actor_class == marker_class)
|
||||
{
|
||||
locations.Add(actor->GetActorLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (locations.Num() == 0)
|
||||
{
|
||||
LogError("No markers");
|
||||
}
|
||||
|
||||
return locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for returning world location of randomly selected mark.
|
||||
*
|
||||
* @return World location vector of mark.
|
||||
*/
|
||||
FVector APresidentAIController::get_random_mark() const
|
||||
{
|
||||
if (marker_locations.Num() == 0)
|
||||
{
|
||||
LogError("No markers");
|
||||
return FVector();
|
||||
}
|
||||
|
||||
const int index = random.RandRange(0, marker_locations.Num() - 1);
|
||||
return marker_locations[index];
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AIController.h"
|
||||
#include "LevelLocation.h"
|
||||
#include "PresidentAIController.generated.h"
|
||||
|
||||
/**
|
||||
@ -15,6 +16,8 @@ class PRESIDENTSBRIGADE_API APresidentAIController : public AAIController
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
APresidentAIController();
|
||||
|
||||
virtual void Tick(float delta) override;
|
||||
|
||||
protected:
|
||||
@ -34,13 +37,10 @@ private:
|
||||
waiting
|
||||
};
|
||||
|
||||
TArray<FVector> get_markers() const;
|
||||
FVector get_random_mark() const;
|
||||
|
||||
/**
|
||||
* List of marker locations.
|
||||
* Level location tracker.
|
||||
*/
|
||||
TArray<FVector> marker_locations;
|
||||
TUniquePtr<LevelLocation> level_location;
|
||||
|
||||
/**
|
||||
* Random number stream.
|
||||
|
Loading…
Reference in New Issue
Block a user