Files
BallisticsDocs/Source/EasyBallistics/Private/Pentrace.cpp
T
2025-07-04 01:09:56 -07:00

52 lines
1.8 KiB
C++

// Copyright 2020 Mookie. All Rights Reserved.
#include "EBBullet.h"
float AEBBullet::PenetrationTrace(FVector StartLocation, FVector EndLocation, TWeakObjectPtr<UPrimitiveComponent, FWeakObjectPtr> Component, EPenTraceType PenTraceType, TEnumAsByte<ECollisionChannel> CollisionChannel, FVector &ExitLocation, FVector &ExitNormal) {
FCollisionQueryParams QueryParams;
QueryParams.bTraceComplex = TraceComplex;
QueryParams.bFindInitialOverlaps = true;
QueryParams.AddIgnoredActor(this); // Ignore self
QueryParams.AddIgnoredActors(IgnoredActors); // Ignore other ignored actors
FHitResult Result;
TArray<FHitResult> MultiResults;
switch (PenTraceType) {
case(EPenTraceType::PT_BackTrace): {
// Use multi-trace to handle multiple surfaces between start and end
bool Hit = GetWorld()->LineTraceMultiByChannel(MultiResults, EndLocation, StartLocation, CollisionChannel, QueryParams);
if (!Hit || MultiResults.Num() == 0) return 1.0f;
// Find the first blocking hit when tracing backwards
for (const FHitResult& HitResult : MultiResults) {
if (HitResult.bBlockingHit) {
ExitNormal = HitResult.Normal;
ExitLocation = HitResult.Location;
return (1.0f - HitResult.Time);
}
}
return 1.0f;
}
case(EPenTraceType::PT_ByComponent): {
if (!Component.IsValid()) return 1.0f;
bool Hit = Component->LineTraceComponent(Result, EndLocation, StartLocation, QueryParams);
if (!Hit) return 1.0f;
ExitNormal = Result.Normal;
ExitLocation = Result.Location;
return (1.0f - Result.Time);
}
case(EPenTraceType::PT_TwoSidedGeometry): {
bool Hit = GetWorld()->LineTraceSingleByChannel(Result, StartLocation, EndLocation, CollisionChannel, QueryParams);
if (!Hit) return 1.0f;
ExitLocation = Result.Location;
ExitNormal = -Result.Normal;
return Result.Time;
}
default:
return 1.0f;
}
}