Hi, I have been trying to make a dynamic selection box for a future RTS game, but have been having some issues getting consistent overlap results with the box component that the player draws. The overall idea of the code is as follows:
- Create a box component in the player
controller. - When the user clicks,
begin drawing mode, and update the
size of the box on tick, as long as
LMB is not released. - When LMB is released, check for overlapping
actors in the final box and save
them as the selected actors.
The problem that I am having is that the box appears to be overlapping actors, but will not return them when LMB is released sometimes (particularly common when the drawn box is quite large). The correct actors are generally returned when the size of the box is relatively small.
I have attached a picture of the collision boxes that appear to be overlapping the actor (the small cuboid), but nothing has been returned. The three key functions in the cpp are also included below (SelectionBox is the drawn box, which is a UBoxComponent).
Any help would be appreciated - struggling to figure out why there are inconsistent results here!
void ASPlayerController::StartSelection()
{
bDrawing = true;
FHitResult Hit;
GetHitResultUnderCursor(ECC_Visibility, false, Hit);
StartPoint = Hit.ImpactPoint;
SelectionBox>SetWorldLocationAndRotation(StartPoint,GetControlRotation());
SelectionBox->SetBoxExtent(FVector::ZeroVector,true);
}
void ASPlayerController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (bDrawing)
{
FHitResult Hit;
GetHitResultUnderCursor(ECC_Visibility, false, Hit);
FVector BoxSize;
BoxSize.X = (Hit.ImpactPoint.X - StartPoint.X)/2;
BoxSize.Y = (Hit.ImpactPoint.Y - StartPoint.Y)/2;
BoxSize.Z = DefaultSelectionDepth;
FVector UpdateStartPoint;
UpdateStartPoint.X = StartPoint.X - (StartPoint.X - Hit.ImpactPoint.X)/2;
UpdateStartPoint.Y = StartPoint.Y - (StartPoint.Y - Hit.ImpactPoint.Y)/2;
UpdateStartPoint.Z = StartPoint.Z;
SelectionBox->SetWorldLocation(UpdateStartPoint,true);
SelectionBox->SetBoxExtent(BoxSize,true);
}
}
void ASPlayerController::CheckSelection()
{
ASBaseUnit* SelectedActor;
// Find newly overlapped actors
TArray<AActor*> Overlapped;
SelectionBox->GetOverlappingActors(Overlapped);
for (uint8 i = 0; i < Overlapped.Num(); ++i)
{
SelectedActor = Cast<ASBaseUnit>(Overlapped[i]);
if (SelectedActor)
{
SelectedActors.Add(SelectedActor);
SelectedActor->ChangeSelectionState(true);
}
}
bDrawing = false;
}