You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
absg/Source/SpaceBattler/Private/WaveSubsystem.cpp

81 lines
2.4 KiB

// Fill out your copyright notice in the Description page of Project Settings.
#include "WaveSubsystem.h"
#include "Kismet/GameplayStatics.h"
void UWaveSubsystem::Init(const TArray<UWave*> InWaves, const int32 CurrWave = 0)
{
CurrentWave = CurrWave;
Waves = InWaves;
}
int32 UWaveSubsystem::SpawnWave(const float InVerticalSpacing, const float InHorizontalOffset, const int InNumRows)
{
NumRows = InNumRows;
HorizontalOffset = InHorizontalOffset;
VerticalSpacing = InVerticalSpacing;
SpawnQueue = Waves[CurrentWave]->GetUnits();
const auto NumUnits = SpawnQueue.Num();
CurrentColumn = 0;
LastSpawnIndex = 0;
TArray<AActor*> SpawnPoints;
UGameplayStatics::GetAllActorsWithTag(GetWorld(), "EnemySpawn", SpawnPoints);
SpawnPoint = SpawnPoints[0];
SpawnUnits();
GetWorld()->GetTimerManager().SetTimer(
SpawnTimerHandle,
this,
&UWaveSubsystem::SpawnUnits,
0.5f,
true);
CurrentWave++;
return NumUnits;
}
void UWaveSubsystem::SpawnUnits()
{
for(auto i = 0; i < NumRows; i++)
{
if(i + LastSpawnIndex >= SpawnQueue.Num())
{
GetWorld()->GetTimerManager().ClearTimer(SpawnTimerHandle);
LastSpawnIndex += i;
return;
}
FActorSpawnParameters SpawnActorParameters = {};
SpawnActorParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
FVector Location = SpawnPoint->GetActorLocation() + FVector(i * -VerticalSpacing + FMath::RandRange(-500.0f, 500.0f), -HorizontalOffset * CurrentColumn + FMath::RandRange(-500.0f, 500.0f), 300);
FRotator Rotation = FRotator(0,-90.0f, 0);
AActor* NewEnemy = GetWorld()->SpawnActor(SpawnQueue[i + LastSpawnIndex]->GetCharacterClass(), &Location, &Rotation, SpawnActorParameters);
if(NewEnemy != nullptr)
{
NewEnemy->Tags.Add(TEXT("enemy"));
USkeletalMeshComponent* Mesh = NewEnemy->FindComponentByClass<USkeletalMeshComponent>();
Mesh->SetCollisionObjectType(ECC_GameTraceChannel2);
}
FHitResult Hit;
FVector TraceStart = NewEnemy->GetActorLocation();
FVector TraceEnd = -NewEnemy->GetActorUpVector() * 10000.0f;
FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(NewEnemy);
NewEnemy->GetWorld()->LineTraceSingleByChannel(Hit, TraceStart, TraceEnd, ECC_WorldStatic, QueryParams);
if(Hit.bBlockingHit)
{
NewEnemy->SetActorLocation(Hit.Location, true, nullptr, ETeleportType::ResetPhysics);
}
}
LastSpawnIndex += NumRows;
CurrentColumn++;
}