AEyeXActorBase* AEyeXPlayerController::FindBySweep(FHitResult& OutHit, const FSceneView* const View, const FVector2D& GazePoint, const FCollisionQueryParams& TraceParams, const FCollisionObjectQueryParams& ObjectParams) { if (SweepIntervals <= 1) { UE_LOG(LogEyeX, Warning, TEXT("Invalid value for SweepIntervals: %i. Must be greater than 0."), SweepIntervals); return nullptr; } UWorld* World = GetWorld(); if (!World) return nullptr; FVector Start, Direction; View->DeprojectFVector2D(GazePoint, Start, Direction); const float TanFOVScaled = GetTanOfFOVAngleScaled(); // Perform sweeps const float DeltaDistance = MaxDistance / SweepIntervals; const FVector DeltaDirection = DeltaDistance * Direction; float CurrentDistance = DeltaDistance / 2; FCollisionShape Shape; AEyeXActorBase* EyeXActor = nullptr; for (int i = 0; i < SweepIntervals; ++i) { const FVector End = Start + DeltaDirection; const float Radius = (i == 0) ? 0.0f : TanFOVScaled * CurrentDistance; // Depends on the view frustrum, size of the screen and the distance. Shape.SetSphere(Radius); if (World->SweepSingle(OutHit, Start, End, FQuat::Identity, Shape, TraceParams, ObjectParams)) { EyeXActor = Cast<AEyeXActorBase>(OutHit.GetActor()); break; } Start = End; CurrentDistance += DeltaDistance; } VisualizeHit(bVisualizeDetection, World, OutHit, Shape.GetSphereRadius()); VisualizeGazePoint(bVisualizeDetection, World, Start); return EyeXActor; }
bool AGameplayAbilityTargetActor_GroundTrace::AdjustCollisionResultForShape(const FVector OriginalStartPoint, const FVector OriginalEndPoint, const FCollisionQueryParams Params, FHitResult& OutHitResult) const { UWorld *ThisWorld = GetWorld(); //Pull back toward player to find a better spot, accounting for the width of our object FVector Movement = (OriginalEndPoint - OriginalStartPoint); FVector MovementDirection = Movement.SafeNormal(); float MovementMagnitude2D = Movement.Size2D(); if (bDebug) { if (CollisionHeight > 0.0f) { DrawDebugCapsule(ThisWorld, OriginalEndPoint, CollisionHeight * 0.5f, CollisionRadius, FQuat::Identity, FColor::Black); } else { DrawDebugSphere(ThisWorld, OriginalEndPoint, CollisionRadius, 8, FColor::Black); } } if ((MovementMagnitude2D < (CollisionRadius * 2.0f)) || (CollisionRadius <= 1.0f)) { return false; //Bad case! } float IncrementSize = FMath::Clamp<float>(CollisionRadius * 0.5f, 25.0f, 250.0f); float LerpIncrement = IncrementSize / MovementMagnitude2D; FHitResult LocalResult; FVector TraceStart; FVector TraceEnd; //This needs to ramp up - the first few increments should be small, then we should start moving in larger steps. for (float LerpValue = CollisionRadius / MovementMagnitude2D; LerpValue < 1.0f; LerpValue += LerpIncrement) { TraceEnd = TraceStart = OriginalEndPoint - (LerpValue * Movement); TraceEnd.Z -= 99999.0f; ThisWorld->SweepSingle(LocalResult, TraceStart, TraceEnd, FQuat::Identity, TraceChannel, CollisionShape, Params); if (!LocalResult.bStartPenetrating) { if (!LocalResult.bBlockingHit) { //This is probably off the map and should not be considered valid. This should not happen in a non-debug map. if (bDebug) { if (CollisionHeight > 0.0f) { DrawDebugCapsule(ThisWorld, LocalResult.Location, CollisionHeight * 0.5f, CollisionRadius, FQuat::Identity, FColor::Yellow); } else { DrawDebugSphere(ThisWorld, LocalResult.Location, CollisionRadius, 8, FColor::Yellow); } } continue; //LocalResult.Location = TraceStart; } if (bDebug) { if (CollisionHeight > 0.0f) { DrawDebugCapsule(ThisWorld, LocalResult.Location, CollisionHeight * 0.5f, CollisionRadius, FQuat::Identity, FColor::Green); } else { DrawDebugSphere(ThisWorld, LocalResult.Location, CollisionRadius, 8, FColor::Green); } } OutHitResult = LocalResult; return true; } if (bDebug) { if (CollisionHeight > 0.0f) { DrawDebugCapsule(ThisWorld, TraceStart, CollisionHeight * 0.5f, CollisionRadius, FQuat::Identity, FColor::Red); } else { DrawDebugSphere(ThisWorld, TraceStart, CollisionRadius, 8, FColor::Red); } } } return false; }
FORCEINLINE_DEBUGGABLE FVector RunBoxTrace(const FVector& StartPos, const FVector& EndPos) { FHitResult OutHit; const bool bHit = World->SweepSingle(OutHit, StartPos, EndPos, FQuat((EndPos - StartPos).Rotation()), Channel, FCollisionShape::MakeBox(Extent), Params); return bHit ? OutHit.ImpactPoint : EndPos; }
FORCEINLINE_DEBUGGABLE FVector RunCapsuleTrace(const FVector& StartPos, const FVector& EndPos) { FHitResult OutHit; const bool bHit = World->SweepSingle(OutHit, StartPos, EndPos, FQuat::Identity, Channel, FCollisionShape::MakeCapsule(Extent.X, Extent.Z), Params); return bHit ? OutHit.ImpactPoint : EndPos; }