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);
}