52 lines
1.8 KiB
C++
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;
|
|
}
|
|
} |