Projectile Movement Issue

Encountered an issue in this section. When testing, the turret fires at the tank normally when in range, however when I click the Fire button to shoot, projectiles just spawn on the ground under the tank. Code follows:

ProjectileBase.cpp

#include “ProjectileBase.h”

#include “Components/StaticMeshComponent.h”

#include “GameFramework/ProjectileMovementComponent.h”

#include “Kismet/GameplayStatics.h”

// Sets default values

AProjectileBase::AProjectileBase()

{

// 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;

ProjectileMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Projectile Mesh"));

ProjectileMesh->OnComponentHit.AddDynamic(this, &AProjectileBase::OnHit);

RootComponent = ProjectileMesh;

ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("Projectile Movement"));

ProjectileMovement->InitialSpeed = MovementSpeed;

ProjectileMovement->MaxSpeed = MovementSpeed;

InitialLifeSpan = 3.0f;

}

// Called when the game starts or when spawned

void AProjectileBase::BeginPlay()

{

Super::BeginPlay();

}

void AProjectileBase::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)

{

AActor* MyOwner = GetOwner();

if(!MyOwner)

{

    return;

}

if(OtherActor && OtherActor != this && OtherActor != MyOwner)

{

    UGameplayStatics::ApplyDamage(OtherActor, Damage, MyOwner->GetInstigatorController(), this, DamageType);

}

Destroy();

}

ProjectileBase.h

#pragma once

#include “CoreMinimal.h”

#include “GameFramework/Actor.h”

#include “ProjectileBase.generated.h”

class UProjectileMovementComponent;

UCLASS()

class TOONTANKS_API AProjectileBase : public AActor

{

GENERATED_BODY()

private:

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))

UProjectileMovementComponent* ProjectileMovement;

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))

UStaticMeshComponent* ProjectileMesh;

UPROPERTY(EditDefaultsOnly, Category = "Damage")

TSubclassOf<UDamageType> DamageType;

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement", meta = (AllowPrivateAccess = "true"))

float MovementSpeed = 1300;

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Damage", meta = (AllowPrivateAccess = "true"))

float Damage = 50;

UFUNCTION()

void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);

public:

// Sets default values for this actor's properties

AProjectileBase();

protected:

// Called when the game starts or when spawned

virtual void BeginPlay() override;

};

Please use a code block by highlighting the text and using the </> button. And could you also show your PawnBase code and blueprint (Tank/Turret)

Sorry about that.

Here is PawnBase.h:

#pragma once

#include "CoreMinimal.h"

#include "GameFramework/Pawn.h"

#include "PawnBase.generated.h"

class UCapsuleComponent;

class AProjectileBase;

UCLASS()

class TOONTANKS_API APawnBase : public APawn

{

    GENERATED_BODY()

private:

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))

    UCapsuleComponent* CapsuleComp;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))

    UStaticMeshComponent* BaseMesh;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))

    UStaticMeshComponent* TurretMesh;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))

    USceneComponent* ProjectileSpawnPoint;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Projectiles", meta = (AllowPrivateAccess = "true"))

    TSubclassOf<AProjectileBase> ProjectileClass;

public:

    // Sets default values for this pawn's properties

    APawnBase();

protected:

    void RotateTurret(FVector LookAtTarget);

    void Fire();

    virtual void HandleDestruction();

};

Here is PawnBase.cpp:

#include "PawnBase.h"

#include "Components/CapsuleComponent.h"

#include "ToonTanks/Actors/ProjectileBase.h"

// Sets default values

APawnBase::APawnBase()

{

    // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.

    PrimaryActorTick.bCanEverTick = true;

    CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Collider"));

    RootComponent = CapsuleComp;

    BaseMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Base Mesh"));

    BaseMesh->SetupAttachment(RootComponent);

    TurretMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Turret Mesh"));

    TurretMesh->SetupAttachment(BaseMesh);

    ProjectileSpawnPoint = CreateDefaultSubobject<USceneComponent>(TEXT("Projectile Spawn Point"));

    ProjectileSpawnPoint->SetupAttachment(TurretMesh);

}

void APawnBase::RotateTurret(FVector LookAtTarget)

{

    FVector LookAtTargetClean = FVector(LookAtTarget.X, LookAtTarget.Y, TurretMesh->GetComponentLocation().Z);

    FVector StartLocation = TurretMesh->GetComponentLocation();

    FRotator TurretRotation = FVector(LookAtTargetClean - StartLocation).Rotation();

    TurretMesh->SetWorldRotation(TurretRotation);

}

void APawnBase::Fire()

{

    if(ProjectileClass)

    {

        FVector SpawnLocation = ProjectileSpawnPoint->GetComponentLocation();

        FRotator SpawnRotation = ProjectileSpawnPoint->GetComponentRotation();

        AProjectileBase* TempProjectile = GetWorld()->SpawnActor<AProjectileBase>(ProjectileClass, SpawnLocation, SpawnRotation);

        TempProjectile->SetOwner(this);

    }

}

void APawnBase::HandleDestruction()

{

    

}

Here are the blueprints as well:

Thank you :slight_smile:

And where have you placed ProjectileSpawnPoint in the viewport?

1 Like

You were right. Spawn point for the tank was at the bottom. That’s fixed it! Unbelievable how seemingly complicated issues are caused by simple mistakes. Thanks for your help :slight_smile:

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms