Hello, I’m trying to implement a marquee selection interface and I was wondering how I might go about retrieving all the units in my world that overlap a rectangle defined in screen space coordinates? Would UWorld->SweepMulti work for this? The comment for this method mentions that it sweeps a sphere against the world, but then the function accepts an FCollisionShape, so I’m not sure if I can actually define a rectangle in screen space that gets swept against the scene or not. Would this be the ideal way to perform a task like this?
USTRUCT()
struct FVRect
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
FVector2D Min;
UPROPERTY()
FVector2D Max;
FVRect(const FVector2D& VPoint1, const FVector2D& VPoint2)
{
//drag topleft to bottom right
if(VPoint1.X < VPoint2.X &&
VPoint1.Y < VPoint2.Y
){
Min = VPoint1;
Max = VPoint2;
}
//drag from bottom right to top left
else if(VPoint1.X > VPoint2.X &&
VPoint1.Y > VPoint2.Y
){
Min = VPoint2;
Max = VPoint1;
}
//drag from bottom left to top right
else if(VPoint1.X < VPoint2.X &&
VPoint1.Y > VPoint2.Y
){
Min = FVector2D(VPoint1.X, VPoint2.Y);
Max = FVector2D(VPoint2.X, VPoint1.Y);
}
//drag from top right to bottom left
else if(VPoint1.X > VPoint2.X &&
VPoint2.Y > VPoint1.Y
){
Min = FVector2D(VPoint2.X, VPoint1.Y);
Max = FVector2D(VPoint1.X, VPoint2.Y);
}
else
{
Min = VPoint2;
Max = VPoint1;
}
}
FVRect()
{
Min = FVector2D(0,0);
Max = FVector2D(500,500);
}
};
#In HUD CPP
//MarqueeAnchor is the first click location in HUD space
//mouse location is current position in HUD space
//update this every tick
RainbowMarquee = FVRect(RainbowMarqueeAnchor,MouseLocation );
//~~~
//process the below every tick
void AVictoryHUD::ProcessMarqueeSelect()
{
//~~~ Reset ~~~
ProjectedRMLocations.Empty();
ProjectedRMActors.Empty();
//~~~ Get Projected Actor Locations ! ~~~
//Joy SMAS
for ( TObjectIterator<AStaticMeshActor> Itr; Itr; ++Itr )
{
if(!UVictoryCore::VIsValid(*Itr)) continue;
//~~~~~~~~~~~~~
//Projected Location
ProjectedRMLocations.Add( Canvas->Project(Itr->GetActorLocation()) );
//Projected Actor
ProjectedRMActors.Add(*Itr);
}
//~~~ Check Actor Locations Inside Marquee ~~~
for(int32 RMItr = 0; RMItr < ProjectedRMLocations.Num(); RMItr++)
{
EachRMLocation = &ProjectedRMLocations[RMItr];
//check cursor in bounds
if (RainbowMarquee.Min.X <= EachRMLocation->X && EachRMLocation->X <= RainbowMarquee.Max.X &&
RainbowMarquee.Min.Y <= EachRMLocation->Y && EachRMLocation->Y <= RainbowMarquee.Max.Y )
{
//If Alt is down, remove, if shift is down, add
if(VictoryPC->ALTDown())
VictoryPC->RemoveFromVSelection(ProjectedRMActors[RMItr]);
else VictoryPC->AddToVSelection(ProjectedRMActors[RMItr],false); //do NOT do undo transform!!!
//add one set of undo transform on LMB release if was dragging, if need to
}
else if ( ! VictoryPC->SHIFTDown()) VictoryPC->RemoveFromVSelection(ProjectedRMActors[RMItr]);
}
}
Hi Morganjdavidson. Did this take care of the issue you were having? If so, please click the check mark to indicate the answer is correct, or confirm that it was correct in a comment and I will take care of that for you.