How do you make a rts selection box?

Ello! How can you make a rts selection box, like this:

image

I hope you can help me

3 Likes

What have you tried so far? What smaller pieces have you broken the problem into? Do you have any initial ideas?

1 Like

you can create a variable storing the mouse position when it clicks and do some
easy math thingies

Explorer:
Screenshot 2022-10-07 162534

LocalScript:

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")

local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local SelectionBox = script.Parent:WaitForChild("SelectionFrame", math.huge) --  "SelectionBox is not a valid member of ScreenGui"

local ClickedOn = nil

UserInputService.InputBegan:Connect(function(Input, GameProcessed)
	if GameProcessed then
		return
	end
	
	if Input.UserInputType == Enum.UserInputType.MouseButton1 then
		ClickedOn = Vector2.new(Mouse.X, Mouse.Y)
		
		SelectionBox.Visible = true
		SelectionBox.Position = UDim2.fromOffset(ClickedOn.X, ClickedOn.Y)
	end
end)

UserInputService.InputEnded:Connect(function(Input)
	if Input.UserInputType == Enum.UserInputType.MouseButton1 then
		ClickedOn = nil
		SelectionBox.Visible = false
	end
end)

UserInputService.InputChanged:Connect(function()
	if ClickedOn then
		local X = Mouse.X - ClickedOn.X
		local Y = Mouse.Y - ClickedOn.Y
		
		SelectionBox.Size = UDim2.fromOffset(X, Y)
	end
end)
7 Likes

Sorry to bug, may I ask what is the best way to implement the function of selection with this ui?

what

what do you mean

Selecting troops or Npc’s for an rts game.

my bad i was confused on what he said

local Camera = workspace.CurrentCamera
local SelectionLocation = -- the location of where the selections thingy be

local function GetSelectedParts()
	local SelectedParts = {}
	
	for i, Part in SelectionLocation:GetDescendants() do
		if not Part:IsA("BasePart") then
			continue
		end
		
		local PosOnScreen = Camera:WorldToScreenPoint(Part.Position)
		-- convert the position to the screen thingy 
		
		if 
			PosOnScreen.X < (SelectionBox.AbsolutePosition.X + SelectionBox.AbsoluteSize.X) and PosOnScreen.X > (SelectionBox.AbsolutePosition.X) and
			PosOnScreen.Y < (SelectionBox.AbsolutePosition.Y + SelectionBox.AbsoluteSize.Y) and PosOnScreen.Y > (SelectionBox.AbsolutePosition.Y)
			-- check if the pos on screen is inside the selection frame
		then
			table.insert(SelectedParts, Part)
		end
	end
	
	return SelectedParts
end
4 Likes

thanks! it works. But, when I try and use left click and then drag the selection box to the right. It does not select troops. It only works when I drag the selection box to the left, how do I fix this?

1 Like

the reason was because the ui size is on negative so the thingy that checks if the position is in the ui gets confused so here is the solution

local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")

local Player = Players.LocalPlayer
local Mouse = Player:GetMouse()
local SelectionBox = script.Parent:WaitForChild("SelectionFrame", math.huge) --  "SelectionBox is not a valid member of ScreenGui"

local Camera = workspace.CurrentCamera
local SelectionLocation = -- the location of where the selections thingy be

local ClickedOn = nil

local function GetSelectedParts()
	local SelectedParts = {}

	for i, Part in SelectionLocation:GetDescendants() do
		if not Part:IsA("BasePart") then
			continue
		end

		local PosOnScreen = Camera:WorldToScreenPoint(Part.Position)

		if 
			PosOnScreen.X < (SelectionBox.AbsolutePosition.X + SelectionBox.AbsoluteSize.X) and PosOnScreen.X > (SelectionBox.AbsolutePosition.X) and
			PosOnScreen.Y < (SelectionBox.AbsolutePosition.Y + SelectionBox.AbsoluteSize.Y) and PosOnScreen.Y > (SelectionBox.AbsolutePosition.Y)
		then
			table.insert(SelectedParts, Part)
		end
	end

	return SelectedParts
end

UserInputService.InputBegan:Connect(function(Input, GameProcessed)
	if GameProcessed then
		return
	end

	if Input.UserInputType == Enum.UserInputType.MouseButton1 then
		ClickedOn = Vector2.new(Mouse.X, Mouse.Y)
		SelectionBox.Position = UDim2.fromOffset(ClickedOn.X, ClickedOn.Y)
	end
end)

UserInputService.InputEnded:Connect(function(Input)
	if Input.UserInputType == Enum.UserInputType.MouseButton1 then
		ClickedOn = nil
		SelectionBox.Visible = false
	end
end)

UserInputService.InputChanged:Connect(function()
	if ClickedOn then
		local X = Mouse.X - ClickedOn.X
		local Y = Mouse.Y - ClickedOn.Y

		if X < 0 then
			SelectionBox.Position = UDim2.fromOffset(ClickedOn.X + X, ClickedOn.Y)
			X = math.abs(X)
		end

		if Y < 0 then
			SelectionBox.Position = UDim2.fromOffset(ClickedOn.X, ClickedOn.Y + Y)
			Y = math.abs(X)
		end

		SelectionBox.Size = UDim2.fromOffset(X, Y)
		SelectionBox.Visible = true
	end
end)

or here are the fixed lines

UserInputService.InputChanged:Connect(function()
	if ClickedOn then
		local X = Mouse.X - ClickedOn.X
		local Y = Mouse.Y - ClickedOn.Y

		if X < 0 then
			SelectionBox.Position = UDim2.fromOffset(ClickedOn.X + X, ClickedOn.Y)
			X = math.abs(X)
		end

		if Y < 0 then
			SelectionBox.Position = UDim2.fromOffset(ClickedOn.X, ClickedOn.Y + Y)
			Y = math.abs(X)
		end

		SelectionBox.Size = UDim2.fromOffset(X, Y)
		SelectionBox.Visible = true
	end
end)
4 Likes

Hey! Sorry if it Bothers you, But I was wondering on how to make the selection box work on any direction. It got quite annoying when trying to select troops.

I don’t know how to make that or add that in.

Could you provide a solution to this (step by step guide) or a script (sorry if it’s rude)

Thanks.

i didnt know what caused the issue but I fixed it somehow

UserInputService.InputBegan:Connect(function(Input, GameProcessed)
	if GameProcessed then
		return
	end

	if Input.UserInputType == Enum.UserInputType.MouseButton1 then
		ClickedOn = Vector2.new(Mouse.X, Mouse.Y)
		SelectionBox.Size = UDim2.fromOffset()
		SelectionBox.Position = UDim2.fromOffset(ClickedOn.X, ClickedOn.Y)
	end
end)
UserInputService.InputChanged:Connect(function()
	if ClickedOn then
		local X = Mouse.X - ClickedOn.X
		local Y = Mouse.Y - ClickedOn.Y
		
		SelectionBox.Position = UDim2.fromOffset(ClickedOn.X - (X < 0 and -X or 0), ClickedOn.Y - (Y < 0 and -Y or 0))
		SelectionBox.Size = UDim2.fromOffset(math.abs(X), math.abs(Y))
		SelectionBox.Visible = true
	end
end)
3 Likes

How did you store them and make them move together?