O PlayerCharacter pode mudar o tipo de PlayerProjectile que está sendo usado durante o jogo. As classes que representam os diversos tipos de PlayerProjectile serão adicionadas em um TArray na classe C++ PlayerCharacter.
Cada elemento do TArray é do tipo TSubclassOf<APlayerProjectile>. O uso do TSubclassOf permite que sejam armazenadas referências para a classe APlayerProjectile ou para qualquer uma de suas classes filhas (subclasses).
O código abaixo é a nova versão do arquivo PlayerCharacter.h contendo as variáveis e função necessárias para fazer a troca de projéteis. O conteúdo novo está em negrito. Observe que antes da macro UCLASS() foi feita uma forward declaration da classe APlayerProjectile. Dessa forma só precisamos adicionar o #include "PlayerProjectile.h" no arquivo cpp.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "PlayerCharacter.generated.h"
class APlayerProjectile;
UCLASS()
class TUTOPART3_API APlayerCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
APlayerCharacter();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
override;
UFUNCTION(BlueprintCallable, Category = Movement)
void MoveForward(float Value);
UFUNCTION(BlueprintCallable, Category = Movement)
void MoveRight(float Value);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Projectile)
TSubclassOf<APlayerProjectile> CurrentProjectileClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Projectile)
TArray< TSubclassOf<APlayerProjectile> > ProjectileClasses;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Projectile)
int32 IndexProjectileClass;
UFUNCTION(BlueprintCallable, Category = Projectile)
void ChangeProjectile();
};
Vamos analisar cada uma das novas declarações:
- TSubclassOf<APlayerProjectile> CurrentProjectileClass: Esta variável armazena a referência da classe do tipo APlayerProjectile que representa o projétil selecionado pelo jogador.
- TArray< TSubclassOf<APlayerProjectile> > ProjectileClasses: Array que armazena todas as referências de classe do tipo APlayerProjectile que podem ser selecionadas pelo jogador.
- int32 IndexProjectileClass: Armazena o índice com a posição no Array do APlayerProjectile selecionado.
- void ChangeProjectile(): Função que muda para o próximo projétil e atualiza as variáveis. Ao chegar no final do Array, retorna para o início.
No arquivo PlayerCharacter.cpp temos a definição da função ChangeProjectile(). Além disso, na função BeginPlay(), a variável CurrentProjectileClass é inicializada com o primeiro elemento do Array, que é o elemento com índice 0. A nova versão do arquivo ficou assim:
#include "PlayerCharacter.h"
#include "PlayerProjectile.h"
// Sets default values
APlayerCharacter::APlayerCharacter()
{
// Set this character to call Tick() every frame.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void APlayerCharacter::BeginPlay()
{
Super::BeginPlay();
if(CurrentProjectileClass == nullptr && ProjectileClasses.Num() > 0)
{
CurrentProjectileClass = ProjectileClasses[0];
}
}
// Called every frame
void APlayerCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
void APlayerCharacter::MoveForward(float Value)
{
AddMovementInput(GetActorForwardVector(), Value);
}
void APlayerCharacter::MoveRight(float Value)
{
AddMovementInput(GetActorRightVector(), Value);
}
void APlayerCharacter::ChangeProjectile()
{
IndexProjectileClass++;
if(IndexProjectileClass == ProjectileClasses.Num())
{
IndexProjectileClass = 0;
}
CurrentProjectileClass = ProjectileClasses[IndexProjectileClass];
}
No próximo artigo vamos fazer os ajustes necessário no Blueprint BP_PlayerCharacter e adicionar os elementos do Array de PlayerProjectile.