No artigo anterior, analisamos o conteúdo da 1ª versão do arquivo EnemyCannon.h. Neste artigo, será explicado o conteúdo do arquivo EnemyCannon.cpp equivalente.
No início do arquivo tem a inclusão dos arquivos cabeçalhos necessários usando as linhas #include. No construtor temos a inicialização dos componentes e da variável FireRate.
#include "EnemyCannon.h"
#include "EnemyProjectile.h"
#include "Components/ArrowComponent.h"
#include "Kismet/GameplayStatics.h"
#include "PlayerProjectile.h"
// Sets default values
AEnemyCannon::AEnemyCannon()
{
PrimaryActorTick.bCanEverTick = true;
RootScene = CreateDefaultSubobject<USceneComponent>(TEXT("RootScene"));
RootComponent = RootScene;
StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
StaticMesh->SetCollisionProfileName(
UCollisionProfile::BlockAllDynamic_ProfileName);
StaticMesh->SetupAttachment(RootScene);
ProjectileSpawnLocation = CreateDefaultSubobject<UArrowComponent>(
TEXT("ProjectileSpawnLocation"));
ProjectileSpawnLocation->SetupAttachment(StaticMesh);
FireRate = 5.f;
}
// Called every frame
void AEnemyCannon::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
FVector Direction = PlayerPawn->GetActorLocation()
- StaticMesh->GetComponentLocation();
FRotator Rotator = FVector(Direction.X, Direction.Y, 0).Rotation();
StaticMesh->SetWorldRotation(Rotator);
}
// Called when the game starts or when spawned
void AEnemyCannon::BeginPlay()
{
Super::BeginPlay();
PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
GetWorldTimerManager().SetTimer(ShotTimerHandle, this,
&AEnemyCannon::ShootCannon, FireRate, true);
}
void AEnemyCannon::ShootCannon()
{
GetWorld()->SpawnActor<AEnemyProjectile>(ProjectileClass,
ProjectileSpawnLocation->GetComponentTransform() );
}
Na função Tick() é feito a lógica para que o canhão sempre aponte na direção do jogador. Primeiro, calculamos o vetor da Direção (Direction) pegando o vetor Location do jogador e subtraindo o vetor Location do canhão.
A estrutura FVector possui uma função chamada Rotation() que retorna um FRotator na direção indicada pelo vetor. Foi criado um FVector baseado no vetor Direction mas desconsiderando a coordenada Z para que o canhão não rotacione para cima e para baixo. O FRotator resultante deste novo FVector foi usado para definir a rotação atual do canhão.
Na função BeginPlay() é obtida a referência à instância que representa o jogador e armazenada na variável PlayerPawn. Depois temos a criação do Timer, cuja referência será armazenada em ShotTimerHandle, e que chamará a função ShootCannon periodicamente usando como intervalo de tempo o valor que está na variável FireRate.
Na função ShootCannon() temos a criação do projétil baseado na classe que está armazenada em ProjectileClass usando o Transform do componente ProjectileSpawnLocation para definir a posição e rotação do projétil.
No próximo artigo veremos as variáveis e funções necessárias para contar os Hits e destruir o canhão.