Possible trouble with collision

I’ve been following the Tanks vs. Zombies C++ tutorial and have run into a problem that I’m having trouble fixing.

When firing a missile, the missile should time out after 1 second and explode or collide with a zombie, deal damage once and then explode. The explosion animation is a Paper2D flipbook. However, my missiles are still active seemingly until the flipbook is finished, meaning that the missiles still deal damage.

Please let me know if you need more information. Any help is appreciated, thank you.

Missile.cpp:
[SPOILER]


// Fill out your copyright notice in the Description page of Project Settings.

#include "Missile.h"
#include "Public/TimerManager.h"
#include "Public/WorldCollision.h"
#include "DamageInterface.h"
#include "Engine/World.h"


// Sets default values
AMissile::AMissile()
{
     // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    Speed = 200.0f;
    Radius = 20.0f;
    DirectDamage = 5;
}

// Called when the game starts or when spawned
void AMissile::BeginPlay()
{
    Super::BeginPlay();

    GetWorldTimerManager().SetTimer(ExplodeTimerHandle, this, &AMissile::Explode, 1.0f);
}

// Called every frame
void AMissile::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    FVector Loc = GetActorLocation();
    FVector DesiredEndLoc = Loc + ((DeltaTime * Speed) * GetTransform().GetUnitAxis(EAxis::X));

    if (UWorld* World = GetWorld())
    {
        FHitResult OutHit;
        FCollisionShape CollisionShape;
        CollisionShape.SetCapsule(Radius, 200.0f);
        if (World->SweepSingleByProfile(OutHit, Loc, DesiredEndLoc, FQuat::Identity, MovementCollisionProfile, CollisionShape))
        {
            SetActorLocation(OutHit.Location);            

            if (IDamageInterface* DamageActor = Cast<IDamageInterface>(OutHit.Actor.Get()))
            {
                DamageActor->RecieveDamage(DirectDamage);
            }

            Explode();
        }
        else
        {
            SetActorLocation(DesiredEndLoc);
        }
    }
}

void AMissile::Explode()
{
    GetWorldTimerManager().ClearTimer(ExplodeTimerHandle);
    SetActorEnableCollision(false);

    OnExplode();
}

void AMissile::OnExplode_Implementation()
{
    Destroy();
}

[/SPOILER]

Missile.h
[SPOILER]


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Missile.generated.h"

UCLASS()
class TANKS_API AMissile : public AActor
{
    GENERATED_BODY()

public:    
    // Sets default values for this actor's properties
    AMissile();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:    
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    /** How fast the missile travels. */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile")
    float Speed;

    /** This missile's radius for collisions. */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile")
    float Radius;

    /** How much damage the missile does. */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile")
    int32 DirectDamage;

    /** Describes what this missle hits. */
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Projectile")
    FName MovementCollisionProfile;

protected:
    void Explode();

    FTimerHandle ExplodeTimerHandle;

    /** What to do when the projectile explodes. The base version just destroys the projectile. */
    UFUNCTION(BlueprintNativeEvent, Category = "Projectile")
    void OnExplode();
    virtual void OnExplode_Implementation();

};

[/SPOILER]

Collision Profile:

Zombie taking 100 hits:
100_hits.gif

Zombie walking into exploded missile:
Zombie_walking_into_smoke.gif

You could either set the DirectDamage to 0 after it is initially applied, better to have a boolean (HasAppliedDamage) that you check whether damage was not applied before applying.

Thanks, Telimaktar.

I ended up setting a bool. The bool will be a good temporary fix to finish the tutorial. I’ve been trying to find the cause of the issue, but I don’t know enough to solve it permanently.