SweepMultiByChannel() causing huge framerate loss (From 120fps to 50fps)

I am trying to create a radar system for my game which will identify enemy ships within a large vicinity.

Every time I get the SweepMultiByChannel() to get my hitResults I suffer a huge frame stutter. I will be running this every six seconds so this is a huge problem for me. Is there a known performance issue for a FCollisionShape::Sphere to be used for a raycast…

I currently have only 2 objects in the game and it really is killing the performance significantly… I should also point out that I have this as a “Radar” component so I can add it to other ships in the future.

Below is the code:

void URadarComponent::RadarRaycast()
{
	//hold a reference to all the objects returned from our radar sweep
	TArray<FHitResult> RadarHitsArray;

	//use the ship location as the end location on the sphere, also set the height to be the radar height.
	FVector ShipLocation = GetOwner()->GetActorLocation();
	ShipLocation.Z += RadarHeight;

	FVector EndLocation = FVector(ShipLocation.X + 45.f, ShipLocation.Y, ShipLocation.Z);	
	
	//Collision Shape is Spherical and range is 1km
	FCollisionShape RadarSphere = FCollisionShape::MakeSphere(RadarDistance);
		
	//Debug lines
	DrawDebugSphere(GetWorld(), ShipLocation, RadarDistance, 6, FColor::Yellow, true, 3.0f, 0U, 0.5f);

	//Now see what it hits	
	bool isHit = GetWorld()->SweepMultiByChannel(RadarHitsArray, ShipLocation, ShipLocation, FQuat::Identity, ECC_RADAR_SHIPS, RadarSphere);	

	if(isHit)
	{
		for(auto& Hit : RadarHitsArray)
		{				
			if(GEngine)
			{
				GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Yellow, FString::Printf(TEXT("Radar Contact: %s "), *Hit.Actor->GetName()));
			}
		}
	}
}

//Fire a radar search every six seconds
void URadarComponent::RadarSweepTimer()
{
	
	GetWorld()->GetTimerManager().SetTimer(RadarSweepTimerHandle, this, &URadarComponent::RadarRaycast, 6.f, true);	
}

Does the radar really need to use physics? You can just check the distance between the ships.

2 Likes

Hi STRiFE.x,

I am fairly new to Unreal and game development, I am not sure what you mean by does the radar need to use physics? Does the SweepMultiByChannel use physics? I just have been reading the documentation for raycasting and can’t see why I would have such a whack on my framerate for simply doing a spherical raycast.

With regard to your answer of ‘just check the distance between ships’? How do you mean…

The two other ways I can think of doing this are:
A Large collsionbox around the ship with whatever crosses it with a tag as ‘radarObject’ will be identified.
Or the way I think your saying to me is to just measure the distance of all actors in the map and just do something like FVector::DistSquared(PlayerLocationVector, OtherShipLocationVector)…

I will need to be able to display the information onto a HUD at some point as well.

Any help or input towards this would be greatly appreceated. I really still don’t understand why I am have a framerate loss just for a sweeptrace though… any light on that would also be appreceated.

I have not used SweepMultiByChannel but these two functions are very slow:

DrawDebugSphere
AddOnScreenDebugMessage

Thanks Babush61, will try the trace again without the debug data and just put the results in a UE_LOG(), Weill update if this helps or if I still am stuck with this drop in performance.
Thanks

UE_LOG () is also slow, the best solution is to make it possible to disable DebugDraw

if (Debug)
{
      Debug Code
}

The real problem is more likely to be that loop you have set up.

Regardless.
You may be better off just “get all actors of class” and printing out their location with a for loop.

It depends on how many total results are possible.
Below 100 actors it should run fine.
Above that, then a collision may be better.

There’s no real reason to use sweep though?
(Sweeping implies movement of the sphere. Radar only responds to the ping).

Something as simple as returning meshes within the collision area would do.
So you can look into

And this allows you to add a component to the ship BP that manages the radar size… hidden in game. With a specific / dedicated trace channel with overlap.
Optimized. As in you turn off physics for it too maybe.

2 Likes

How is this any relevant to the question? lol These are debug functions that will never be in a release build of a game (they are automatically removed). It’s irrelevant if it’s slow or not.

You always compile the game to watch the FPS?

1 Like

Was mentioned above, but instead of doing a physics sweep why not just iterate ships? Would be way faster.

For each ship
   If within radar range
       draw radar blip

How many objects can likely appear on radar? If you only have 100 or less a simple for loop is fine. If you have thousands there are many ways to easily optimize. Grids, hashing, trees, etc.

1 Like

I’d still do it with multi threading. Because it’s a good conceptual exercise …