single line reflecting on all objects

Here is the corrected code !
DrawSingleReflect.h:

// DrawSingleReflect.h
// But: Dessine un seul rayon qui se réfléchit sur les objets rencontrés.
//code OK

#pragma once

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

UCLASS()
class ESSAI_API ADrawSingleReflect : public AActor
{
	GENERATED_BODY()

public:
	// Constructeur
	ADrawSingleReflect();

protected:
	// BeginPlay (appelé au démarrage)
	virtual void BeginPlay() override;

public:
	// Tick (appelé à chaque frame)
	virtual void Tick(float DeltaTime) override;

	// Acteur/objet qui est le point de départ du rayon initial
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SingleReflect")
	AActor* StartActor;

	// Longueur du rayon à chaque segment
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SingleReflect")
	float RayLength = 1000.0f;

	// Épaisseur du rayon
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SingleReflect")
	float LineThickness = 5.0f;

	// Durée du rayon (en secondes)
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SingleReflect")
	float LineDuration = -1.0f; // -1 pour une durée infinie

	// Couleur du rayon initial
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SingleReflect")
	FLinearColor LineColor = FLinearColor::Red;

	// Couleur du rayon réfléchi
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SingleReflect")
	FLinearColor ReflectedLineColor = FLinearColor::Green;

	// Couleur de la normale
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SingleReflect")
	FLinearColor NormalLineColor = FLinearColor::Blue;

	// Longueur de la normale
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SingleReflect")
	float NormalLineLength = 100.0f;

	// Nombre maximum de réflexions
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SingleReflect")
	int32 MaxReflections = 5;

private:
	FVector CurrentRayStart;
	FVector CurrentRayDirection;
	int32 ReflectionCount;

	void DrawReflectedRay(); // Ajouté

};

et DrawSingleReflect.cpp:

#include "DrawSingleReflect.h"
#include "DrawDebugHelpers.h"
#include "Logging/LogMacros.h"
#include "Engine/World.h"

ADrawSingleReflect::ADrawSingleReflect()
{
	PrimaryActorTick.bCanEverTick = true;
}

void ADrawSingleReflect::BeginPlay()
{
	Super::BeginPlay();

	if (!StartActor)
	{
		UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::BeginPlay - StartActor non valide!"));
	}
}

void ADrawSingleReflect::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (!StartActor) return;

	// Réinitialise les points de départ à chaque tick
	CurrentRayStart = StartActor->GetActorLocation();
	CurrentRayDirection = StartActor->GetActorForwardVector();

	// Dessine les réflexions
	DrawReflectedRay();
}



void ADrawSingleReflect::DrawReflectedRay()
{
	int32 ReflectionCounter = 0;
	FVector RayStart = CurrentRayStart;
	FVector RayDirection = CurrentRayDirection.GetSafeNormal();

	FVector PreviousImpactPoint = FVector::ZeroVector;

	while (ReflectionCounter < MaxReflections)
	{
		FVector TraceEnd = RayStart + RayDirection * RayLength;

		FHitResult HitResult;
		FCollisionQueryParams Params;
		Params.AddIgnoredActor(this);
		Params.AddIgnoredActor(StartActor);

		bool bHit = GetWorld()->LineTraceSingleByChannel(
			HitResult,
			RayStart,
			TraceEnd,
			ECollisionChannel::ECC_Visibility,
			Params
		);

		// >>> DÉPLACER LE CODE DE DESSIN ICI <<<
		FVector DrawEnd = bHit ? HitResult.ImpactPoint : TraceEnd;

		DrawDebugLine(
			GetWorld(),
			RayStart,
			DrawEnd,
			(ReflectionCounter == 0) ? LineColor.ToFColor(true) : ReflectedLineColor.ToFColor(true),
			false,
			LineDuration,
			0,
			LineThickness
		);
		// >>> FIN DU DÉPLACEMENT <<<

		if (bHit && HitResult.GetActor())
		{
			FVector ImpactPoint = HitResult.ImpactPoint;
			FVector Normal = HitResult.Normal.GetSafeNormal();
			Params.AddIgnoredActor(HitResult.GetActor());

			// Stop si on est trop proche de l'impact précédent (évite les doubles rebonds au même point)
			if (FVector::DistSquared(PreviousImpactPoint, ImpactPoint) < 1.0f)
			{
				UE_LOG(LogTemp, Warning, TEXT("Impact trop proche de l'ancien. Arrêt."));
				break;
			}
			PreviousImpactPoint = ImpactPoint;

			// Dessin de la normale
			DrawDebugLine(
				GetWorld(),
				ImpactPoint,
				ImpactPoint + Normal * NormalLineLength,
				NormalLineColor.ToFColor(true),
				true,
				LineDuration,
				0,
				LineThickness
			);

			// Calcul du vecteur réfléchi
			FVector Reflected = FMath::GetReflectionVector(RayDirection, Normal).GetSafeNormal();

			if (Reflected.IsNearlyZero())
			{
				UE_LOG(LogTemp, Warning, TEXT("Vecteur reflechi nul. Arret."));
				break;
			}

			// Préparer le prochain rebond
			RayStart = ImpactPoint + Reflected * 0.5f; // Petit offset pour éviter rebond au même point
			RayDirection = Reflected;

			UE_LOG(LogTemp, Warning, TEXT("Réflexion %d: Impact sur %s à %s. Nouvelle direction: %s"),
				ReflectionCounter + 1,
				*HitResult.GetActor()->GetName(),
				*ImpactPoint.ToString(),
				*RayDirection.ToString()
			);

			UE_LOG(LogTemp, Warning, TEXT("RayStart: %s"), *RayStart.ToString());
			UE_LOG(LogTemp, Warning, TEXT("Hit point: %s"), *HitResult.ImpactPoint.ToString());
			UE_LOG(LogTemp, Warning, TEXT("Normal: %s"), *HitResult.Normal.ToString());
			UE_LOG(LogTemp, Warning, TEXT("Incoming Dir: %s"), *RayDirection.ToString());
			UE_LOG(LogTemp, Warning, TEXT("Reflected Dir: %s"), *Reflected.ToString());

			ReflectionCounter++;
		}
		else
		{
			break; // Plus rien à toucher
		}
	}

	UE_LOG(LogTemp, Warning, TEXT("Total réflexions: %d"), ReflectionCounter);
}