SweepMultiByChannel doesn't return enough results

I’m trying to use SweepMultiByChannel to sweep a sphere through the world (like Sphere Trace in Blueprint) from the player to a distance in front of them, to get an array of every actor hit by the sphere.

The problem I’m having is that it only returns multiple hits if the player is standing directly on top of a bunch of actors. The sweep only returns a max of 1 hit otherwise and for the life of me I cannot figure out why… It’s almost like it only checks the start location for multiple hits and the sweep through the world only gets 1 hit…

What am I doing wrong here? Can this be implemented in a better way?

TArray TraceHits;
FVector CameraFwVector = Camera->GetForwardVector();
FVector TraceStart = Camera->GetComponentLocation();
FVector TraceEnd = TraceStart + (CameraFwVector * TraceDistance);
FCollisionShape SweepShape = FCollisionShape::MakeSphere(TraceRadius);

if (GetWorld()->SweepMultiByChannel(TraceHits, TraceStart, TraceEnd, FQuat::Identity, ECollisionChannel::ECC_Visibility, SweepShape))
	if (TraceHits.Num() > 1)
		for (auto& hr : TraceHits)
			GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Orange, FString::Printf(TEXT("You are hitting: %s"), *hr.ImpactPoint.ToString()));
		GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Orange, FString::Printf(TEXT("You are hitting: %s"), *TraceHits[0].ImpactPoint.ToString()));

I can’t see any problem in your code. (I’m using the First person project in this example.)

Try this (simplified version - no need to check if (TraceHits.Num() > 1))

void AFPCharacter::Tick(float DeltaSeconds) // call SweepMultiByChannel in Tick if you want to check continuously
    TArray<FHitResult> TraceHits;
    FVector CameraFwVector = FirstPersonCameraComponent->GetForwardVector();
    FVector TraceStart = FirstPersonCameraComponent->GetComponentLocation();
    FVector TraceEnd = TraceStart + (CameraFwVector * TraceDistance); // 1000.0f
    FCollisionShape SweepShape = FCollisionShape::MakeSphere(500.0f);

    if (GetWorld()->SweepMultiByChannel(TraceHits, TraceStart, TraceEnd, FQuat::Identity, ECC_Visibility, SweepShape))
        for (FHitResult& hr : TraceHits)
            GEngine->AddOnScreenDebugMessage(INDEX_NONE, 5.0f, FColor::Orange,
                                                 TEXT("You are hitting: %s"), *hr.ImpactPoint.ToString()));

Thanks for the reply, however this code seems to have the same problem. At first glance it looks like it works, but that is only because the radius of the cast is huge so the start trace is hitting all of the actors surrounding the player. If you reduce it to 100.0 (1 meter) then you’ll notice it returns 1 hit max outside of the trace start location.

Unfortunately I went ahead and recreated my code in blueprint using the sphere trace node and I’m getting the same problem which makes me think this is either a limitation of channel tracing or with using visibility/camera as the trace channel. Not really sure why this would be but I can’t think of any other explanation.

Turns out this was just due to my lack of understanding of Unreal traces.

Tracing/sweeping by Channel only returns the overlaps up to the first blocking hit. In my defense, the debug drawing for these sweep/trace types does not indicate that at all.


If anybody has trouble with collision responses :slight_smile: