Hi,
Here’s a DrawSingleReflect class whose CPP needs to be corrected because there is only one reflection regardless of the maximum number of reflections.
Here’s the .h:
// DrawSingleReflect.h
// But: Dessine un seul rayon qui se réfléchit sur les objets rencontrés.
#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;
};
and here the .cpp:
// DrawSingleReflect.cpp
#include "DrawSingleReflect.h"
#include "DrawDebugHelpers.h"
#include "Logging/LogMacros.h"
#include "Engine/World.h"
ADrawSingleReflect::ADrawSingleReflect()
{
PrimaryActorTick.bCanEverTick = true;
ReflectionCount = 0;
}
void ADrawSingleReflect::BeginPlay()
{
Super::BeginPlay();
if (StartActor)
{
CurrentRayStart = StartActor->GetActorLocation();
CurrentRayDirection = StartActor->GetActorForwardVector();
ReflectionCount = 0;
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::BeginPlay - Start: %s, Direction: %s"), *CurrentRayStart.ToString(), *CurrentRayDirection.ToString());
}
else
{
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::BeginPlay - StartActor non valide!"));
}
}
void ADrawSingleReflect::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick() appelee, StartActor: %s, ReflectionCount: %d"), StartActor ? *StartActor->GetName() : TEXT("nullptr"), ReflectionCount);
if (StartActor)
{
if (ReflectionCount < MaxReflections)
{
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick - Current Direction: %s"), *CurrentRayDirection.ToString());
FVector TraceEnd = CurrentRayStart + CurrentRayDirection * RayLength;
FHitResult HitResult;
FCollisionQueryParams CollisionParams;
CollisionParams.AddIgnoredActor(this);
CollisionParams.AddIgnoredActor(StartActor);
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick - Trace Start: %s, End: %s"), *CurrentRayStart.ToString(), *TraceEnd.ToString());
bool bHit = GetWorld()->LineTraceSingleByChannel(
HitResult,
CurrentRayStart,
TraceEnd,
ECollisionChannel::ECC_Visibility,
CollisionParams
);
// Dessin du segment de rayon actuel
DrawDebugLine(
GetWorld(),
CurrentRayStart,
TraceEnd,
(ReflectionCount == 0) ? LineColor.ToFColor(true) : ReflectedLineColor.ToFColor(true),
false,
LineDuration,
0,
LineThickness
);
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick - Ligne dessinee de %s a %s"), *CurrentRayStart.ToString(), *TraceEnd.ToString());
if (bHit)
{
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick - Hit detecte sur: %s a %s, Normal: %s"), HitResult.GetActor() ? *HitResult.GetActor()->GetName() : TEXT("nullptr"), *HitResult.ImpactPoint.ToString(), *HitResult.Normal.ToString());
AActor* HitActor = HitResult.GetActor();
if (HitActor)
{
FVector ImpactPoint = HitResult.ImpactPoint;
FVector NormalVector = HitResult.Normal;
FVector IncidentVector = (ImpactPoint - CurrentRayStart).GetSafeNormal();
CurrentRayDirection = FMath::GetReflectionVector(IncidentVector, NormalVector);
// *** INSERER L'EXTRAIT DE CODE ICI ***
if (CurrentRayDirection.IsZero())
{
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick - Vecteur reflechi nul, arret des reflexions."));
// Option 1: Arrêter (comportement actuel)
return;
// Option 2: Choisir une direction par defaut (exemple: leger decalage vers le haut)
// CurrentRayDirection = NormalVector.GetSafeNormal() + FVector(0.1f, 0.1f, 0.1f).GetSafeNormal();
}
// *** FIN DE L'INSERTION ***
CurrentRayStart = ImpactPoint;
ReflectionCount++;
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick - Reflexion %d"), ReflectionCount);
// Dessin de la normale
DrawDebugLine(
GetWorld(),
ImpactPoint,
ImpactPoint + NormalVector * NormalLineLength,
NormalLineColor.ToFColor(true),
false,
LineDuration,
0,
LineThickness
);
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick - Normale dessinee a %s"), *ImpactPoint.ToString());
}
else
{
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick - Hit sur un acteur non valide."));
return; // Arrêter le traitement pour cette frame
}
}
else
{
UE_LOG(LogTemp, Warning, TEXT("ADrawSingleReflect::Tick - Aucun hit detecte."));
return; // Arrêter le traitement pour cette frame
}
}
}
}
Can you correct it?
thanks