How do I make my collision loop?

I currently have this setup (.cpp):

AFire::AFire(const class FObjectInitializer& ObjectInitializer)
{
	ProxSphere = ObjectInitializer.CreateDefaultSubobject<USphereComponent>(this, TEXT("Sphere Component"));
	ProxSphere->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepWorldTransform);
	ProxSphere->SetSphereRadius(32.f);
	ProxSphere->OnComponentBeginOverlap.AddDynamic(this, &AFire::Prox);


 	// 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;
	PrimaryActorTick.bStartWithTickEnabled = true;

}

void AFire::Prox_Implementation(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)
{
	if (Cast<AMyCharacter>(OtherActor) == nullptr)
	{
		return;
	}
	if (Cast<AMyCharacter>(OtherActor))
	{
		AMyCharacter* Character = Cast<AMyCharacter>(OtherActor);
		Character->Damage(Character->GetHp(), 6.f);
	}
}

.h:

   	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Collision")
    		USphereComponent* ProxSphere;
    	UFUNCTION(BlueprintNativeEvent, Category = "Collision")
    		void Prox(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult);

This is successful in damaging my character every time I walk onto it, but it doesn’t loop so if I stand on top of it I don’t continue to take damage. I can’t move this to the Tick class.

I tried adding a while loop, but it made my program crash:

void AFire::Prox_Implementation(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)
{
	if (Cast<AMyCharacter>(OtherActor) == nullptr)
	{
		return;
	}
	if (Cast<AMyCharacter>(OtherActor))
	{
		while (Cast <AMyCharacter>(OtherActor))
		{
		AMyCharacter* Character = Cast<AMyCharacter>(OtherActor);
		Character->Damage(Character->GetHp(), 6.f);

		}
	}
	

}

Is there any way to make my collision tick so it can check every second if my character is colliding with it?

What you can do is to use a timer to try to inflict damage to a set of characters in the fire area every time it ticks. Every time a character enters the area (via OnComponentBeginOveralp) you add the character to this set, and every time a character exits the area you remove it from the set.

The additional codes would look something like this (please note that this code below is written from the top of my head and have not been tested, it’s just to give you a rough idea of how it is done) :

in Fire.h

...

/** Handle to the damage timer. */
UPROPERTY(Transient)
FTimerHandle DamageTimerHandle;

UPROPERTY(Transient)
TArray<TWeakObjectPtr<AMyCharacter>> CharactersInTheArea;

/** How often the damage is applied to characters in the area. */
UPROPERTY(EditAnywhere, Category="Damage")
float DamageRate = 0.5;

UFUNCTION()
void ApplyDamageToCharacters();
...

in AFire.cpp

AFire::AFire( const FObjectInitializer& ObjectInitializer)
{
	...
	ProxSphere->OnComponentBeginOverlap.AddDynamic(this, &AFire::HandleBeginOverlap);	
	ProxSphere->OnComponentEndOverlap.AddDynamic(this, &AFire::HandleEndOverlap);
}

void AFire::BeginPlay()
{
	...
	GetWorld()->GetTimerManager().SetTimer(DamageTimerHandle, this, &AFire::ApplyDamageToCharacters, DamageRate, false);	
	...
}

void AFire::HandleBeginOverlap( AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult )
{
	if ( AMyCharacter* Character = Cast<AMyCharacter>(OtherActor) )
	{
		CharactersInArea.AddUnique( Character );
	}
}

void AFire::HandleEndOverlap( AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex )
{
	if ( AMyCharacter* Character = Cast<AMyCharacter>(OtherActor) )
	{
		CharactersInArea.Remove( Character );
	}	
}


void AFire::ApplyDamageToCharactersInTheArea()
{
	for ( TWeakObjectPtr<AMyCharacter>& CharPtr : CharactersInTheArea )
	{
		if ( CharPtr.IsValid() )
		{
			CharPtr->Damage( Character->GetHp(), 6.f );
		}
	}
}

There are of course a lot of additional things you can do with this kind of implementation, if you want to optimize the code you can play around with the timer handle on only run it when there’s actually character in the area, you can tweak the damage rate to match the fire particle to give a bit of immersion to the game, etc.

This seems like an unorthodox way of doing it, and I may end up having to do it this way, but I also feel like there should be a way to create a collision event in my tick function. I just don’t know how.