(for some reason i cannot tag the post to the correct lecture, even when creating the post directly in the lecture)
Hi,
I have problems with damage registering in both tank and turret pawns. I have reached the steps until the UE_LOG in ActorDied function, but no output log of damage applied is shown, wich makes me think damage is not registering, but I cannot find any problems in the code.
Health component is included in both Pawns, and default health is set to 100.0f; I did had the problem in the previous lectures that “AddDynamic” did not work properly if Blueprint class was already existing; I created again the BP thinking it may be the same issue, but no success.
Code for ProjectileBase
#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"));
//spawn destruction
RootComponent = ProjectileMesh;
ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("Projectile Movement"));
ProjectileMovement->InitialSpeed = MovementSpeed;
ProjectileMovement->MaxSpeed = MovementSpeed;
InitialLifeSpan = 3.0f;
}
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);
}
//play destroy effects
Destroy();
}
// Called when the game starts or when spawned
void AProjectileBase::BeginPlay()
{
Super::BeginPlay();
ProjectileMesh->OnComponentHit.AddDynamic(this, &AProjectileBase::OnHit);
}
Code for TankGameModeBase
void ATankGameModeBase::BeginPlay()
{
//Get references and game/win lose conditions
//Call HandleGameStart() to initialise the start countdown, turret activation, pawn check, etc
}
void ATankGameModeBase::ActorDied(AActor* DeadActor)
{
//check what type of actor died. If turret, tally. If player->go to lose condition
UE_LOG(LogTemp, Warning, TEXT("A pawn died"));
}
void ATankGameModeBase::HandleGameStart()
{
//initialise the start countdown, turret activation, pawn check, etc
//Call blueprint version GameStart()
}
void ATankGameModeBase::HandleGameOver(bool PlayerWon)
{
//see if player has destroyed all the turrets->show win result if yes
//else if turret destroyed player->show lose result
//call blueprint version GameOver(bool PlayerWon)
}
Code for HealthComponent
#include "HealthComponent.h"
#include "ToonTanks/GameModes/TankGameModeBase.h"
#include "Kismet/GameplayStatics.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 = false;
// ...
}
// Called when the game starts
void UHealthComponent::BeginPlay()
{
Super::BeginPlay();
Health = DefaultHealth;
GameModeRef = Cast<ATankGameModeBase>(UGameplayStatics::GetGameMode(GetWorld()));
GetOwner()->OnTakeAnyDamage.AddDynamic(this, &UHealthComponent::TakeDamage);
}
void UHealthComponent::TakeDamage(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatedBy, AActor* DamageCauser)
{
if (Damage == 0 || Health <= 0) { return; }
Health = FMath::Clamp(Health - Damage, 0.0f, DefaultHealth); //avoid drop health below 0 or above max
if (Health <= 0)
{
if(GameModeRef)
{
GameModeRef->ActorDied(GetOwner());
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Health component has no reference to GameMode"));
}
}
}
Thanks a lot.
Aitor