I did everything the Video told me and double checked to make sure but they wont destroy, I have done Multiple test, I first Put a UE_LOG To print The name of the actor that was Hit, The damage Done and Health, From this screenshot The Health does Go past Zero But the Were not destroyed
It Turns Out The HandleDestruction Function was not being called because I added a UE_LOG In there and It wasn’t Showing
I don’t Know Whats Wrong, But Here is the Code to HealthComponent. Cpp,
// Fill out your copyright notice in the Description page of Project Settings.
#include "HealthComponent.h"
#include "Kismet/GameplayStatics.h"
#include "ToonTanksGameMode.h"
// Sets default values for this component's properties
UHealthComponent::UHealthComponent()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
}
// Called when the game starts
void UHealthComponent::BeginPlay()
{
Super::BeginPlay();
Health = MaxHealth;
GetOwner()->OnTakeAnyDamage.AddDynamic(this, &UHealthComponent::DamageTaken);
ToonTanksGameMode = Cast<AToonTanksGameMode>(UGameplayStatics::GetGameMode(this));
}
// Called every frame
void UHealthComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}
void UHealthComponent::DamageTaken(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* Insigator, AActor* DamageCauser)
{
if (Damage <= 0.f) return;
Health -= Damage;
if (Health <= 0 && ToonTanksGameMode)
{
ToonTanksGameMode->ActorDied(DamagedActor);
UE_LOG(LogTemp, Display, TEXT("%s: Took %f Damage, and Health is now %f"), *DamagedActor->GetName(), Damage, Health);
}
}
HealthComponent.h
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "HealthComponent.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class TOONTANKS_API UHealthComponent : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UHealthComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
private:
UPROPERTY(EditAnywhere)
float MaxHealth = 100.f;
float Health = 0.f;
UFUNCTION(BlueprintCallable)
void DamageTaken(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* Insigator, AActor* DamageCauser);
class AToonTanksGameMode* ToonTanksGameMode;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
};
Tower.Cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Tower.h"
#include "Tank.h"
#include "Kismet/GameplayStatics.h"
#include "TimerManager.h"
void ATower::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (InFireRange())
{
RotateTurrent(Tank->GetActorLocation());
}
}
void ATower::HandleDestruction()
{
Super::HandleDestruction();
UE_LOG(LogTemp, Warning, TEXT("Destroyed!"));
Destroy();
}
void ATower::BeginPlay()
{
Super::BeginPlay();
Tank = Cast<ATank>(UGameplayStatics::GetPlayerPawn(this, 0));
GetWorldTimerManager().SetTimer(FireTimerHandle, this, &ATower::CheckFireCondition, FireWait, true);
}
void ATower::CheckFireCondition()
{
if (InFireRange())
{
Fire();
}
}
bool ATower::InFireRange()
{
if (Tank)
{
float DistanceChecked = FVector::Dist(GetActorLocation(), Tank->GetActorLocation());
if (DistanceChecked <= FireRange)
{
return true;
}
}
return false;
}
Tower.h
#include "CoreMinimal.h"
#include "BasePawn.h"
#include "Tower.generated.h"
/**
*
*/
UCLASS()
class TOONTANKS_API ATower : public ABasePawn
{
GENERATED_BODY()
public:
virtual void Tick(float DeltaTime) override;
void HandleDestruction();
protected:
virtual void BeginPlay() override;
private:
// How far It can attack the player
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "ture"), Category = "Combat")
float FireRange = 10;
// Fire Delay
FTimerHandle FireTimerHandle;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Combat", meta = (AllowPrivateAccess = "true"))
float FireWait = 2.f;
void CheckFireCondition();
// Access The Tank Class
class ATank* Tank;
bool InFireRange();
};
Tank.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Tank.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Kismet/GameplayStatics.h"
ATank::ATank()
{
SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Spring Arm"));
SpringArm->SetupAttachment(RootComponent);
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
Camera->SetupAttachment(SpringArm);
}
void ATank::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis(TEXT("MoveForward"), this, &ATank::MoveForward);
PlayerInputComponent->BindAxis(TEXT("Turn"), this, &ATank::TurnRightAndLeft);
PlayerInputComponent->BindAction(TEXT("Fire"), IE_Pressed, this, &ATank::Fire);
}
void ATank::BeginPlay()
{
Super::BeginPlay();
TankPlayerController = Cast<APlayerController>(GetController());
}
void ATank::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (TankPlayerController)
{
FHitResult HitResult;
TankPlayerController->GetHitResultUnderCursor(ECC_Visibility, false, HitResult);
RotateTurrent(HitResult.ImpactPoint);
}
}
void ATank::MoveForward(float Value)
{
FVector DeltaLocation = FVector::ZeroVector;
// X * DeltaTime * Speed
DeltaLocation.X = Value * Speed * UGameplayStatics::GetWorldDeltaSeconds(this);
AddActorLocalOffset(DeltaLocation, true);
}
void ATank::TurnRightAndLeft(float Value)
{
FRotator DeltaRotation = FRotator::ZeroRotator;
// Yaw = Value * DeltaTime * TurnRate
DeltaRotation.Yaw = Value * TurnRate * UGameplayStatics::GetWorldDeltaSeconds(this);
AddActorLocalRotation(DeltaRotation, true);
}
void ATank::HandleDestruction()
{
Super::HandleDestruction();
SetActorHiddenInGame(true);
SetActorTickEnabled(false);
}
Tank.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BasePawn.h"
#include "Tank.generated.h"
UCLASS()
class TOONTANKS_API ATank : public ABasePawn
{
GENERATED_BODY()
public:
// Sets the Default Properties for the Pawn
ATank();
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
private:
// Camera Variables
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* SpringArm;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
class UCameraComponent* Camera;
// Speed Variables
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"), Category = "Movement")
float Speed = 300;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement", meta = (AllowPrivateAccess = "true"))
float TurnRate = 100.f;
// Movement Functions
UFUNCTION(BluePrintCallable)
void MoveForward(float Value);
UFUNCTION(BluePrintCallable)
void TurnRightAndLeft(float Value);
APlayerController* TankPlayerController;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
void HandleDestruction();
APlayerController* GetTankPlayerController() const { return TankPlayerController; };
};
BasePawn.Cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "BasePawn.h"
#include "Projectile.h"
#include "Components/CapsuleComponent.h"
#include "Kismet/GameplayStatics.h"
// Sets default values
ABasePawn::ABasePawn()
{
// 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;
TankBase = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Tank Base Mesh"));
TankBase->SetupAttachment(RootComponent);
TankTurrent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Tank Turrent Mesh"));
TankTurrent->SetupAttachment(TankBase);
ProjectileSpawnPoint = CreateDefaultSubobject<USceneComponent>(TEXT("Projectile Spawn Component"));
ProjectileSpawnPoint->SetupAttachment(TankTurrent);
}
void ABasePawn::RotateTurrent(FVector LookatTarget)
{
FVector ToTarget = LookatTarget - TankTurrent->GetComponentLocation();
FRotator LookAtRotation = FRotator(0.f, ToTarget.Rotation().Yaw, 0.f);
TankTurrent->SetWorldRotation(
FMath::RInterpTo(TankTurrent->GetComponentRotation(),
LookAtRotation,
UGameplayStatics::GetWorldDeltaSeconds(this),
TurrentSpinRate
));
}
void ABasePawn::Fire()
{
FVector Location = ProjectileSpawnPoint->GetComponentLocation();
FRotator Rotation = ProjectileSpawnPoint->GetComponentRotation();
auto Projectile = GetWorld()->SpawnActor<AProjectile>(ProjectileClass, Location, Rotation);
Projectile->SetOwner(this);
}
void ABasePawn::HandleDestruction()
{
// TODO:
// Visual and Sound effectS
}
and BasePawn.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "BasePawn.generated.h"
UCLASS()
class TOONTANKS_API ABasePawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ABasePawn();
protected:
// Rotate Turrent Function
UFUNCTION(BlueprintCallable)
void RotateTurrent(FVector LookatTarget);
UPROPERTY(EditAnywhere, Category = "Movement")
float TurrentSpinRate = 5.f;
UPROPERTY(EditDefaultsOnly, Category = "Combat")
TSubclassOf<class AProjectile> ProjectileClass;
void Fire();
private:
// Compnents
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = "true"))
class UCapsuleComponent* CapsuleComp;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = "true"))
UStaticMeshComponent* TankBase;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = "true"))
UStaticMeshComponent* TankTurrent;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Components", meta = (AllowPrivateAccess = "true"))
USceneComponent* ProjectileSpawnPoint;
public:
void HandleDestruction();
};
If there is Anything Wrong Please Let me know
Edit: The reason The turrents are not locking on to me is because I Change the fire radius to 0 to test