GetActorsInSelectionRectangle()

Hey guys, I’m currently trying to do a multiple unit selection with GetActorsInSelectionRectangle(). The selection kinda works, but not accurately. Whenever I’m doing the selection rectangle, it gets characters that are not within the bounds of the rectangle itself.
Here are some screen shots (pay attention to the Output Log for Selected characters, they are updated on each call to the DrawHud() function, also notice where my selection rectangle is):

  1. no character selected
  2. 1 character selected
  3. 2 characters selected
  4. 3 characters selected

My characters don’t have cameras attached nor colliders that extend this far away from them: http://i.imgur.com/OOSSC7q.png
I tried changing the call to GetActorsInSelectionRectangle() and set bActorMustBeFullyEnclosed to true, but still no change. I’ve been trying to fix this for 3 days now, but I think it’s time to ask for help.
This is my code so far:

In my HUD’s DrawHUD() function:

void AMyHUD::DrawHUD()

{

//Player->bDragging is true when the player presses the left mouse button, false when released
if (Player->bDragging)
{
	//Player->InitialMousePosition is a 2D Vector that store's the mouse position in screen coordinates when the player presses the left mouse button (does not update each Tick)
	//CurrentMousePosition (also a 2D vector) updates each DrawHUD() call with the current mouse position
	DrawRect(FColorList::Green.WithAlpha(80), Player->InitialMousePosition.X, Player->InitialMousePosition.Y,
		CurrentMousePosition.X - Player->InitialMousePosition.X, CurrentMousePosition.Y - Player->InitialMousePosition.Y);

	//Multiple select only if the player has dragged around the mouse at least 20 units on either axis
	if (FMath::Abs(CurrentMousePosition.X - Player->InitialMousePosition.X) >= 20 ||
		FMath::Abs(CurrentMousePosition.Y - Player->InitialMousePosition.Y) >= 20)
	{
		//Player->SelectedCharacters is an array that stores my specific kind of Character
		Player->SelectedCharacters.Empty();
		
		GetActorsInSelectionRectangle(Player->InitialMousePosition, CurrentMousePosition, Player->SelectedCharacters);
	}
}

}

On my main pawn/player (it is automatically possessed by the player when the game begins):

//Called when the left mouse button is pressed

void ARTSCamera::OnSelectBegin()

{

bDragging = true;

APlayerController* PlayerController = UGameplayStatics::GetPlayerController(this, 0);
if (PlayerController)
{
	PlayerController->GetMousePosition(InitialMousePosition.X, InitialMousePosition.Y);
	FHitResult OutHitResult;
	PlayerController->GetHitResultUnderCursorByChannel((ETraceTypeQuery)ECC_Visibility, true, OutHitResult);
	
	if (OutHitResult.bBlockingHit)
	{
		ARTSRelatedCharacter* Character = Cast<ARTSRelatedCharacter>(OutHitResult.GetActor());
		//If we clicked a character then select that one character. HUD takes care of multiple selection.
		if (Character)
		{
			SelectedCharacters.Empty();
			SelectedCharacters.Add(Character);
		}
		else
		{
			//if we didn't click a character then deselect them all
			SelectedCharacters.Empty();
		}
	}
}

}

//Called when the left mouse button is released

void ARTSCamera::OnSelectEnd()

{

bDragging = false;

}

I think there must be something wrong with the coordinates, I just feel like the green rectangle and the coordinates that I’m sending to the GetActorsInSelectionRectangle() don’t match.
Any help will be greatly appreciated. Thanks!

I know this is SO old… but did you ever find out the solution to this problem?

I have the EXACT same thing happening, I’ve been searching for a solution for days and I tried changing the coordinates around so many ways, because I came to the same conclusion that it must be the issue…

There are two modes.
In one mode, the full bounding box of the actor needs to be inside the rectangle.
In the other mode, an actor is included as soon as its bounding box overlaps the rectangle even a little bit.
Note that the “bounding box” may include invisible geometry/colliders, too.

You can attempt to make it better in three ways:

  1. Expand the rectangle value before you pass it to the function, and use the “entirely inside” mode.
  2. Shrink the rectanble value before you pass it to the function, and use the “any overlap” mode.
  3. Use the “any overlap” mode, but run a separate filtering function that tests whether “enough” of the object is inside – for example, whether the center of the object, projected to the screen, falls within the rectangle.

However, there’s also a third problem: When using a cinematic camera, with letterboxing / black bars, the rectangle will not use the same coordinate system as the camera, and you will get a different active selection rectangle than what’s drawn on the screen. If this is the problem, the only solution I’ve found is to turn off letterboxing.

Thank you for those suggestions!!

I just discovered it must be the camera because it is much more accurate when the actor I’m trying to select is at the bottom middle of the screen. But when it’s farther from that the selection becomes off.

I’m not sure if there is any letterboxing going on, as I didn’t add that in and have never used it before. Not sure if letterboxing is default with the camera I am using but I will check that, thank you again!

I am sure it is not invisible geometry/colliders I made sure of that.
I tried to expand and contract the rectangle values as well but that only made it better when dragging the rectangle downwards and made it worse dragging it upwards. It did change the coords, but since this wasn’t the root of the problem, it couldn’t fix it and just changed the problem haha.

The coordinates for both ‘Draw Rect’ and ‘Get Actors in Selection Rectangle’ should be correct. The mouse pointer starts and ends exactly where the rectangle is drawn:

Actors are being selected before they are inside the rectangle.
image

If I move the actors to the bottom center of the screen then the selection area is much more accurate but still not correct.

I’ve done a bunch of different things to try to amend the Mouse Start Position and Mouse End Position variables. Also I have tried to get more accurate values for the variables using different methods as well but it only makes it worse or just changed the problem.

Since the rectangle is selecting units too high up and too far to the left I tried to just change the ‘Current Mouse Position’ variable like this…

This works when making the rectangle from top of the screen to the bottom, but causes the problem to persist when you are drawing the rect from the bottom of the screen to the top:
image

image

I hope this all makes sense. The only thing I can think of now is to detect whether you are drawing up or drawing down and then changing the ‘Current Mouse Position’ variable in different ways based on that. But that doesn’t sound like a good solution because whenever the box overlaps the actor will still be based on where the actors are on the screen.

Been trying to get this down for a few days.
Again, any help is appreciated. :]

I found a solution!!!

Since “Get Actors in Selection Rectangle” is not accurate based on camera position, I found this code you can add after the selection rectangle to make the selection and deselection become accurate to the rect itself instead of the world position.

Just follow this guy’s examples in his pictures and it will fix it.

Basically it gets the actor’s location and converts it to screen location then checks if it is inside the rectangle or not.

This is something I was thinking about doing but I didn’t know how.

1 Like