Neste artigo vamos criar uma classe base C++ para representar os projéteis teleguiados que são disparados pelos canhões inimigos.
No Content Browser, acesse a pasta TutoPart3 que está dentro da pasta C++ Classes. Clique com o botão direito em um espaço livre e escolha a opção New C++ Class...:
Na tela seguinte, escolha a classe Actor como classe pai e clique no botão Next.
No campo Name coloque EnemyProjectile. No campo Path, mantenha a pasta padrão do projeto. Clique no botão Create Class.
A classe EnemyProjectile usará quatro tipos de componentes:
- USphereComponent: É usado como componente Root e para o teste de colisão.
- UStaticMeshComponent: Contém o Static Mesh que representará visualmente o projétil.
- UParticleSystemComponent: Componente com um emissor de partículas que será usado para simular um efeito de fogo no projétil.
- UProjectileMovementComponent: Componente usado para movimentar o projétil. Será configurado para seguir o jogador.
Adicione a declaração dos componentes no arquivo EnemyProjectile.h que ficará assim:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "EnemyProjectile.generated.h"
UCLASS()
class TUTOPART3_API AEnemyProjectile : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AEnemyProjectile();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
UStaticMeshComponent* StaticMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
class USphereComponent* CollisionComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
class UParticleSystemComponent* Particles;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
class UProjectileMovementComponent* ProjectileMovement;
};
No arquivo EnemyProjectile.cpp, temos a inicialização dos componentes feita no construtor. Não esqueça de adicionar as linhas #include dos componentes.
#include "EnemyProjectile.h"
#include "Engine/CollisionProfile.h"
#include "Components/SphereComponent.h"
#include "Particles/ParticleSystemComponent.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Kismet/GameplayStatics.h"
// Sets default values
AEnemyProjectile::AEnemyProjectile()
{
PrimaryActorTick.bCanEverTick = true;
InitialLifeSpan = 10.f;
CollisionComponent = CreateDefaultSubobject<USphereComponent>(
TEXT("CollisionComponent"));
RootComponent = CollisionComponent;
CollisionComponent->InitSphereRadius(25.f);
CollisionComponent->SetCollisionProfileName(
UCollisionProfile::BlockAllDynamic_ProfileName);
StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
StaticMesh->SetupAttachment(CollisionComponent);
Particles = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("Particles"));
Particles->SetupAttachment(StaticMesh);
ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(
TEXT("ProjectileMovement"));
ProjectileMovement->InitialSpeed = 300.f;
ProjectileMovement->MaxSpeed = 300.f;
ProjectileMovement->bRotationFollowsVelocity = true;
ProjectileMovement->bIsHomingProjectile = true;
ProjectileMovement->HomingAccelerationMagnitude = 300.f;
ProjectileMovement->ProjectileGravityScale = 0.f;
}
// Called when the game starts or when spawned
void AEnemyProjectile::BeginPlay()
{
Super::BeginPlay();
APawn* PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
if(PlayerPawn)
{
ProjectileMovement->HomingTargetComponent = PlayerPawn->GetRootComponent();
}
}
// Called every frame
void AEnemyProjectile::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
Fiz os seguintes passos para configurar o UProjectileMovementComponent como um projétil teleguiado:
- Atribuí true à variável bRotationFollowsVelocity para que o projétil rotacione quando mudar de direção.
- Atribuí true à variável bIsHomingProjectile para indicar que este é um projétil teleguiado.
- Atribuí um valor para a variável HomingAccelerationMagnitude que indica a aceleração que o projétil se moverá em direção ao alvo. Utilizei o mesmo valor da velocidade do projétil.
- Removi a força de gravidade do projétil atribuindo o valor 0 à variável ProjectileGravityScale.
- O último passo é atribuir um USceneComponent à variável HomingTargetComponent que será usado como alvo. Isto é feito na função BeginPlay(). O alvo é o RootComponent do jogador.
Compile o código C++. Os Assets de Static Mesh e de Particle System serão selecionadas nos Blueprint filhos. Além disso, os valores iniciais atribuídos aos componentes podem ser modificados em Blueprints filhos.