Skip to content

Instantly share code, notes, and snippets.

@danyspin97
Created December 15, 2015 16:26
Show Gist options
  • Save danyspin97/49de52478a9c224b6ef5 to your computer and use it in GitHub Desktop.
Save danyspin97/49de52478a9c224b6ef5 to your computer and use it in GitHub Desktop.
Spawning Order from .cvs in UE4
#include "StoryGameMode.h"
#include "Enemy.h"
#include "Pooling.h"
#include "EnemySpawnerHandler.h"
// Sets default values
AEnemySpawnerHandler::AEnemySpawnerHandler()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
// Replace with AMyLevelActorScript and put in this file the FLevelData
EnemyDataTable.Empty();
static ConstructorHelpers::FObjectFinder<UDataTable> EnemyDataTable_Object(TEXT("DataTable'/Game/Data/EnemyWaveFirstLevel.EnemyWaveFirstLevel'"));//New->Nuovastringa);TEXT("DataTable'/Game/Data/EnemyDataTable_FirstLevel'"));
//EnemyDataTableForFirstLevel = EnemyDataTable_Object.Object;
EnemyDataTable.Add(EnemyDataTable_Object.Object);
}
void AEnemySpawnerHandler::SetLevelSpawning(FString LevelName)
{
// Set the datatable for selected level as null because it will store the new datable for the level wanted
ThisLevelData = NULL;
// Set enemy spawned to 0
EnemyCont = 0;
// Empty this array
EnemiesClassForThisLevel.Empty();
EnemiesSequenceForThisLevel.Empty();
// Search in the first Row of every DataTable until ThisLevelData != NULL or all the DataTable has been read
for (int32 i = 0; i < EnemyDataTable.Num(), ThisLevelData == NULL; i++)
{
// Create a context for reading Row of Datatable - needed
static const FString ContextString(TEXT("GENERAL"));
if (EnemyDataTable[i])
{
// Create a reference for a structure that contains all the variable of the first row of the current DataTable
FEnemyWaveReader* GOLookupRow = EnemyDataTable[i]->FindRow<FEnemyWaveReader>("1", ContextString);
// If that row exist
if (GOLookupRow)
{
// Is the LevelName of the Row the same of the wanted level?
if (GOLookupRow->EnemyWaveName == LevelName)
{
// We found the wanted list of enemies. Store it in ThisLevelData
ThisLevelData = EnemyDataTable[i];
}
}
}
}
// The searching has just finished. Did we find the DataTable?
if (ThisLevelData)
{
// Create a context for reading Row of Datatable - needed
static const FString ContextString(TEXT("GENERAL"));
// Read each row
for (int i = 2; i < (ThisLevelData->GetTableData().Num()); i++)
{
// If the next enemy class has been added to the sequenceArray
bool bThisRowEnemyAdded = false;
// Access the variables like GOLookupRow->Blueprint_Class, GOLookupRow->Usecode
FString Entry = FString::FromInt(i);
FEnemyWaveReader* GOLookupRow = ThisLevelData->FindRow<FEnemyWaveReader>(FName(*Entry), ContextString);
if (GOLookupRow)
{
// Search if the next enemy class in sequence is inside EnemiesClassForThisLevel
if (EnemiesClassForThisLevel.Num() != 0)
{
for (int32 j = 0; j < EnemiesClassForThisLevel.Num(), !bThisRowEnemyAdded; j++)
{
// Compare the class name with the array element class name
if (GOLookupRow->EnemyWaveName == EnemiesClassForThisLevel[j]->GetName())
{
// Add it to the sequence
EnemiesSequenceForThisLevel.Add(&EnemiesClassForThisLevel[j]);
// Added
bThisRowEnemyAdded = true;
}
}
}
// Did we found the next enemy class in EnemiesClassForThisLevel? If not search it in Enemies
if (!bThisRowEnemyAdded)
{
for (int32 j = 0; j < Enemies.Num(); j++)
{
//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, Enemies[j]->GetName());
//GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, Enemy->EnemyName);
if (GOLookupRow->EnemyWaveName == Enemies[j]->GetName())
{
// Add the class in this variable
int32 l = EnemiesClassForThisLevel.Add(Enemies[j]);//FEnemyInfo(Enemies[j]->GetName(), Enemies[j]->GetClass()));
// Add the class to the sequence
EnemiesSequenceForThisLevel.Add(&EnemiesClassForThisLevel[l]);
// Added
bThisRowEnemyAdded = true;
}
}
}
// If we didn't add the enemy, log an error
if (!bThisRowEnemyAdded)
{
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Black, FString::Printf(TEXT("ENEMY NOT FOUND")));
}
}
}
}
}
void AEnemySpawnerHandler::SpawnNextEnemy(const FVector& Location, const FRotator& Rotation)
{
TActorIterator<APooling> Pool(GetWorld());
if (EnemyCont < EnemiesSequenceForThisLevel.Num())
{
Pool->PoolEnemy(GetWorld(), *EnemiesSequenceForThisLevel[EnemyCont], Location, Rotation);
EnemyCont++;
}
}
#pragma once
#include "GameFramework/Actor.h"
#include "EnemySpawnerHandler.generated.h"
class AEnemy;
UCLASS()
class AEnemySpawnerHandler : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AEnemySpawnerHandler();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
// Read all DataTable of Enemies and find the one for the level choosed, then set an array of enemies list for each enemy in order
void SetLevelSpawning(FString LevelName);
void SpawnNextEnemy(const FVector& Location, const FRotator& Rotation);
// o-- Lookup table for Enemies spawining in levels data - Loaded from CSV/Excel
//UPROPERTY(EditDefaultsOnly, Category = Data)
TArray<class UDataTable*> EnemyDataTable;
// Contains the blueprints reference for all enemies in the game
UPROPERTY(EditDefaultsOnly, Category = SpawningBP)
TArray<TSubclassOf<AEnemy>> Enemies;
TArray<FString> EnemiesName;
// Reference to the DataTable of the level selected or already in game
class UDataTable* ThisLevelData;
TArray<TSubclassOf<AEnemy>> EnemiesClassForThisLevel;
//TArray<struct FEnemyInfo> EnemiesClassForThisLevel;
// Store the seqence of enemies spawning during this level
TArray<TSubclassOf<AEnemy>*> EnemiesSequenceForThisLevel;
//TArray<struct FEnemyInfo*> EnemiesSequenceForThisLevel;
// The number of wave in this level
//int32 WaveNumber;
// The number the enemy spawned in this wave
int32 EnemyCont;
};
USTRUCT(BlueprintType, Blueprintable)
struct FEnemyWaveReader : public FTableRowBase
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY()
FString EnemyWaveName;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment