How to do it...

  1. Create a new Actor subclass in the editor, which we will name Barracks:

  1. Then, add the following implementation to the class:
UCLASS()
class CHAPTER_04_API ABarracks : public AActor
{
GENERATED_BODY()

public:
// Sets default values for this actor's properties
ABarracks();

protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;

public:
// Called every frame
virtual void Tick(float DeltaTime) override;

UPROPERTY()
UStaticMeshComponent* BuildingMesh;

UPROPERTY()
UParticleSystemComponent* SpawnPoint;

UPROPERTY()
UClass* UnitToSpawn;

UPROPERTY()
float SpawnInterval;

UFUNCTION()
void SpawnUnit();

UFUNCTION()
void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

UPROPERTY()
FTimerHandle SpawnTimerHandle;

};
  1. Add the following code to the constructor:
#include "Barracks.h"
#include "Particles/ParticleSystemComponent.h"
#include "BarracksUnit.h"


// Sets default values
ABarracks::ABarracks()
{
// 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;

BuildingMesh = CreateDefaultSubobject<UStaticMeshComponent>(
"BuildingMesh");

SpawnPoint = CreateDefaultSubobject<UParticleSystemComponent>(
"SpawnPoint");

SpawnInterval = 10;

auto MeshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(
TEXT("Static
Mesh'/Engine/BasicShapes/Cube.Cube'"));


if (MeshAsset.Object != nullptr)
{
BuildingMesh->SetStaticMesh(MeshAsset.Object);
}

auto ParticleSystem =
ConstructorHelpers::FObjectFinder<UParticleSystem>
(TEXT("ParticleSystem'/Engine/Tutorial/SubEditors/TutorialAssets
/TutorialParticleSystem.TutorialParticleSystem'"));


if (ParticleSystem.Object != nullptr)
{
SpawnPoint->SetTemplate(ParticleSystem.Object);
}

SpawnPoint->SetRelativeScale3D(FVector(0.5, 0.5, 0.5));
UnitToSpawn = ABarracksUnit::StaticClass();
}

Currently, we do not have the BarracksUnit class created, so you'll see Visual Studio complain. We'll implement that as soon as we finish up the Barracks class.

  1. Add the following code to the BeginPlay function:
// Called when the game starts or when spawned
void ABarracks::BeginPlay()
{
Super::BeginPlay();

RootComponent = BuildingMesh;
SpawnPoint->AttachTo(RootComponent);
SpawnPoint->SetRelativeLocation(FVector(150, 0, 0));
GetWorld()->GetTimerManager().SetTimer(SpawnTimerHandle,
this, &ABarracks::SpawnUnit, SpawnInterval, true);
}
  1. Create the implementation for the SpawnUnit function:
void ABarracks::SpawnUnit() 
{ 
  FVector SpawnLocation = SpawnPoint->GetComponentLocation(); 
  GetWorld()->SpawnActor(UnitToSpawn, &SpawnLocation); 
}

  1. Implement the overridden EndPlay function:
void ABarracks::EndPlay(const EEndPlayReason::Type 
EndPlayReason) { Super::EndPlay(EndPlayReason); GetWorld()->GetTimerManager().ClearTimer(SpawnTimerHandle); }
  1. Next, create a new character subclass, BarracksUnit, and add one property:
UPROPERTY() 
UParticleSystemComponent* VisualRepresentation; 
    1. You'll need to add the following #include to get access to the UParticleSystemComponent class:
    #include "Particles/ParticleSystemComponent.h"
    1. Initialize the component in the constructor implementation:
    VisualRepresentation = 
    CreateDefaultSubobject<UParticleSystemComponent>("SpawnPoin
    t");auto ParticleSystem =
    ConstructorHelpers::FObjectFinder<UParticleSystem>(TEXT("Pa
    rticleSystem'/Engine/Tutorial/SubEditors/TutorialAssets/Tut
    orialParticleSystem.TutorialParticleSystem'")); if (ParticleSystem.Object != nullptr) { SpawnPoint->SetTemplate(ParticleSystem.Object); } SpawnPoint->SetRelativeScale3D(FVector(0.5, 0.5, 0.5)); SpawnCollisionHandlingMethod =
    ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
    1. Attach the visual representation to the root component:
    void ABarracksUnit::BeginPlay() 
    { 
      Super::BeginPlay(); 
      SpawnPoint->AttachTo(RootComponent); 
    }
    1. Lastly, add the following to the Tick function to get the spawned actor moving:
    SetActorLocation(GetActorLocation() + FVector(10, 0, 0)); 
    1. Compile your project. Place a copy of the barracks actor into the level. You can then observe it spawning the character at fixed intervals.

    If all went well, you should be able to drag and drop a Barracks object into the world and play the game. Afterwards, you'll notice objects (BarracksUnit objects) being spawned from a singular point and continually moving in a direction!