Posible to code "multiple gui selection" just like the one in studio?

Im trying to code a selection gui(the white frame studio has around the two guis


but im trying to code it to where it works no matter if the ancestors arent the same or if its using “offset or scale” but is doesnt work

heres my code

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local UIS = game:GetService("UserInputService")
local imageframe = script.Parent.Octaves
local GuiCollisionService = require(game:GetService("ReplicatedStorage").GuiCollisionService)


local function Hovering(Frame)
	local MousePos = game:GetService("UserInputService"):GetMouseLocation() - game:GetService("GuiService"):GetGuiInset()
	local Guis = player:WaitForChild("PlayerGui"):GetGuiObjectsAtPosition(MousePos.X, MousePos.Y)

	for _, Gui in Guis do
		if Gui == Frame then
			return true
		end
	end
	return false
end

UIS.InputBegan:connect(function(input)	

	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		local oldframe = script.Parent:FindFirstChild("Select")
		if oldframe == nil then
			local frame = game.ReplicatedStorage.Assets.Select:Clone()
			frame.Parent = script.Parent
			frame.Name = ("Select")
			frame.BackgroundTransparency = 0.8
			frame.BackgroundColor3 = Color3.new(0.666667, 0, 0)
			local uistroke = Instance.new("UIStroke")
			uistroke.Color = Color3.new(0.333333, 0.333333, 0.498039)
			uistroke.Parent = frame
			frame.Position = UDim2.new(0, mouse.X - frame.AbsolutePosition.X, 0, mouse.Y - frame.AbsolutePosition.Y)
			while true do
				task.wait()
				frame.Size = UDim2.new(0, mouse.X - frame.AbsolutePosition.X, 0, mouse.Y - frame.AbsolutePosition.Y)
			end
		else
			if not Hovering(oldframe) then
				local group = game.ReplicatedStorage.Functions.GetSelected:Invoke()
				for i, region in pairs(group) do
					region.UIStroke.Enabled = false
				end
				oldframe:Destroy()
				local frame = game.ReplicatedStorage.Assets.Select:Clone()
				frame.Parent = script.Parent
				frame.Name = ("Select")
				frame.BackgroundTransparency = 0.8
				frame.BackgroundColor3 = Color3.new(0.666667, 0, 0)
				local uistroke = Instance.new("UIStroke")
				uistroke.Parent = frame
				uistroke.Color = Color3.new(0.333333, 0.333333, 0.498039)
				frame.Position = UDim2.new(0, mouse.X - frame.AbsolutePosition.X, 0, mouse.Y - frame.AbsolutePosition.Y)
				while true do
					task.wait()
					frame.Size = UDim2.new(0, mouse.X - frame.AbsolutePosition.X, 0, mouse.Y - frame.AbsolutePosition.Y)
				end
			end
		end
	end
end)



UIS.InputEnded:connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		wait()
		local frame = script.Parent:FindFirstChild("Select")
		if frame ~= nil then
			local selected = script.Parent.Select:Clone()
			selected.Parent = frame.Parent
			selected.BackgroundColor3 = Color3.new(0.333333, 0.333333, 0.498039)
			frame.Size = UDim2.new(frame.AbsoluteSize.X, frame.AbsoluteSize.Y)
			frame:destroy()
			wait(0.2)
			local group = game.ReplicatedStorage.Functions.GetSelected:Invoke()
			local nearestPos = 100000
			local furthestPos = 0
			local nearest
			local furthest
			for i, note in pairs(group) do
				local distance = (note.AbsolutePosition-script.Parent.AbsolutePosition).Magnitude
				if distance < nearestPos then
					nearestPos = distance
					nearest = note
				end
			end
			for i, note in pairs(group) do
				local distance = (note.AbsolutePosition-script.Parent.AbsolutePosition).Magnitude
				if distance > nearestPos then
					furthestPos = distance
					furthest = note
				end
			end
			local corners = GuiCollisionService:getGuiCorners(nearest.Parent)
			if corners == nil then return end
			selected.Position = UDim2.new(0,nearest.Position.X.Offset,0, nearest.AbsoluteSize.Y + nearest.Parent.Position.Y.Offset)
			print(selected.Position)

		else
			return
		end	
	end
end)

imageframe.MouseLeave:Connect(function()
	wait()
	local frame = script.Parent:FindFirstChild("Select")
	if frame ~= nil then
		local Select = script.Parent.Select:Clone()
		Select.Parent = frame.Parent
		Select.BackgroundColor3 = Color3.new(0.333333, 0.333333, 0.498039)
		frame.Size = UDim2.new(frame.AbsoluteSize.X, frame.AbsoluteSize.Y)
		frame:destroy()
	else
		return
	end	
end)

and hers the gui collision service(got it from RuizuKun_Dev)

local GuiCollisionService = {}
GuiCollisionService.__index = GuiCollisionService
local mouse = game.Players.LocalPlayer:GetMouse()
local function intersects (p, edge)
	local x1, y1 = edge.a.X, edge.a.Y
	local x2, y2 = edge.b.X, edge.b.Y

	local x3, y3 = p.X, p.Y
	local x4, y4 = p.X + 2147483647, p.Y
	
	local den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)

	if den == 0 then return false end

	local t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den
	local u = -((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / den
	
	if t and u and t > 0 and t < 1 and u > 0 then
		return true
	end
	
	return false
end

local function solidCollision(gui1,gui2) -- special thanks to RuizuKun_Dev
	local pos1, size1 = gui1.AbsolutePosition, gui1.AbsoluteSize;
	local pos2, size2 = gui2.AbsolutePosition, gui2.AbsoluteSize;

	local IsColliding, MTV = GuiCollisionService.isColliding(gui1, gui2)
	if IsColliding then
		local EdgeDifferences_Array = {
			Vector2.new(pos1.X - (pos2.X + size2.X), 0);
			Vector2.new((pos1.X + size1.X) - pos2.X, 0);
			Vector2.new(0, pos1.Y - (pos2.Y + size2.Y));
			Vector2.new(0, (pos1.Y + size1.Y) - pos2.Y);
		};
		table.sort(EdgeDifferences_Array, function(A, B) return A.magnitude < B.magnitude; end);
		MTV = EdgeDifferences_Array[1];
	end;
	return IsColliding, MTV or Vector2.new();
end;

local function getCorners(guiObject0)
		local pos = Vector2.new(guiObject0.Position.X.Offset,guiObject0.Position.Y.Offset)
		local size = Vector2.new(guiObject0.Size.X.Offset,guiObject0.Size.Y.Offset)
		local rotation = guiObject0.Rotation--Change offset to scale if you want
	
			local a = pos + size/2 - math.sqrt((size.X/2)^2 + (size.Y/2)^2) * Vector2.new(math.cos(math.rad(rotation) + math.atan2(size.Y, size.X)), math.sin(math.rad(rotation) + math.atan2(size.Y, size.X)))
			local b = pos + size/2-math.sqrt((size.X/2)^2 + (size.Y/2)^2) * Vector2.new(math.cos(math.rad(rotation) - math.atan2(size.Y, size.X)), math.sin(math.rad(rotation) - math.atan2(size.Y, size.X)))
			local c = pos + size/2+math.sqrt((size.X/2)^2 + (size.Y/2)^2) * Vector2.new(math.cos(math.rad(rotation) + math.atan2(size.Y, size.X)), math.sin(math.rad(rotation) + math.atan2(size.Y, size.X)))
			local d = pos + size/2+math.sqrt((size.X/2)^2 + (size.Y/2)^2) * Vector2.new(math.cos(math.rad(rotation) - math.atan2(size.Y, size.X)), math.sin(math.rad(rotation) - math.atan2(size.Y, size.X)))

			return{ 
				topleft = a, 
				bottomleft = b, 
				topright = d, 
				bottomright = c 
			}
end


local function checkCollisions(collider, hitter)	
	if collider.solid then
		local IsColliding, MTV = solidCollision(hitter.i, collider.i);
		if IsColliding then
			if hitter.t then
				for i, tween in ipairs(hitter.t) do
					if tween.PlaybackState == Enum.PlaybackState.Playing then
						tween:Pause()
						table.remove(hitter.t, i)
					end
				end 					
			end
			hitter.i.Position = hitter.i.Position - UDim2.new(0, MTV.X, 0, MTV.Y); 
		end;
	end

	if GuiCollisionService.isColliding(hitter.i, collider.i) then
		return true
	end	
	
	return false
end

local function check (hitter, colliders, h)
	local collidingWith = {}

	for _, collider in ipairs(colliders) do
		if h then
			if hitter.i.ZIndex == collider.i.ZIndex then
				if checkCollisions(collider, hitter) then
					table.insert(collidingWith, collider.i)
				end
			end
		else
			if checkCollisions(collider, hitter) then
				table.insert(collidingWith, collider.i)
			end
		end 
	end

	if #collidingWith > 0 then
		return collidingWith
	end

	return nil
end

local function inRange(num, range)
	return num > range.Min and num < range.Max
end
function GuiCollisionService:MouseBetweenPoints(pointA,pointB)
	local mouseVector = Vector2.new(mouse.X,mouse.Y)
	local pointAVector = Vector2.new(pointA.X.Offset,pointA.Y.Offset)
	local pointBVector = Vector2.new(pointB.X.Offset,pointB.Y.Offset)
	return ((mouseVector.X > pointAVector.X and mouseVector.Y > pointAVector.Y) and (mouseVector.X < pointBVector.X and mouseVector.Y < pointBVector.Y))
end

function GuiCollisionService:MouseInFrame(frame)
	local pointAVector = frame.AbsolutePosition
	local pointBVector = frame.AbsolutePosition + frame.AbsoluteSize
	return GuiCollisionService:MouseBetweenPoints(UDim2.fromOffset(pointAVector.X,pointAVector.Y),UDim2.fromOffset(pointBVector.X,pointBVector.Y))
end

function GuiCollisionService:getGuiCorners(guiObject0)
	if guiObject0 == nil then return end
	local pos = Vector2.new(guiObject0.Position.X.Offset,guiObject0.Position.Y.Offset)
	local size = Vector2.new(guiObject0.Size.X.Offset,guiObject0.Size.Y.Offset)
	local rotation = guiObject0.Rotation--Change offset to scale if you want

	local a = pos + size/2-math.sqrt((size.X/2)^2 + (size.Y/2)^2) * Vector2.new(math.cos(math.rad(rotation) + math.atan2(size.Y, size.X)), math.sin(math.rad(rotation) + math.atan2(size.Y, size.X)))
	local b = pos + size/2-math.sqrt((size.X/2)^2 + (size.Y/2)^2) * Vector2.new(math.cos(math.rad(rotation) - math.atan2(size.Y, size.X)), math.sin(math.rad(rotation) - math.atan2(size.Y, size.X)))
	local c = pos + size/2+math.sqrt((size.X/2)^2 + (size.Y/2)^2) * Vector2.new(math.cos(math.rad(rotation) + math.atan2(size.Y, size.X)), math.sin(math.rad(rotation) + math.atan2(size.Y, size.X)))
	local d = pos + size/2+math.sqrt((size.X/2)^2 + (size.Y/2)^2) * Vector2.new(math.cos(math.rad(rotation) - math.atan2(size.Y, size.X)), math.sin(math.rad(rotation) - math.atan2(size.Y, size.X)))

	return{ 
		topleft = a, 
		bottomleft = b, 
		topright = d, 
		bottomright = c 
	}
end


function GuiCollisionService.isInCore(gui0, gui1)
	assert(typeof(gui0) == "Instance" and typeof(gui1) == "Instance", "argument must be an instance")
	if gui0.AbsoluteSize.X > gui1.X or gui0.AbsolutePosition.Y > gui1.Y then return false end
	
	local corners0, corners1 = getCorners(gui0), getCorners(gui1)
	
	local X = NumberRange.new(corners1[1].X, corners1[4].X)
	local Y = NumberRange.new(corners1[1].Y, corners1[2].Y)
	
	local cornersInside = 0
	
	for _, corner in ipairs(corners0) do
		if inRange(corner.X, X) and inRange(corner.Y, Y) then
			cornersInside += 1
		end
	end
	
	if cornersInside == 4 then
		return true
	end
	
	return false
end

function GuiCollisionService.isColliding(guiObject0, guiObject1)
	if not typeof(guiObject0) == "Instance" or not typeof(guiObject1) == "Instance" then error("argument must be an instance") return end
		local ap1 = guiObject0.Position.X.Offset
		local as1 = guiObject0.Size.X.Offset
		local sum = ap1 + as1
		local ap2 = guiObject1.Position.X.Offset
		local as2 = guiObject1.Size.X.Offset
		local sum2 = ap2 + as2
		local corners0 = getCorners(guiObject0)
		local corners1 = getCorners(guiObject1)

		local edges = {
			{
				a = corners1.topleft,
				b = corners1.bottomleft
			},
			{
				a = corners1.topleft,
				b = corners1.topright
			},
			{
				a = corners1.bottomleft,
				b = corners1.bottomright
			},
			{
				a = corners1.topright,
				b = corners1.bottomright
			}
		}
		
		local collisions = 0
		
		for _, corner in pairs(corners0) do
			for _, edge in pairs(edges) do			
				if intersects(corner, edge) then
					collisions += 1
				end			
			end
		end
		
		if collisions%2 ~= 0 then
			return true
		end
		
		if (ap1 < sum2 and sum > ap2) then
			return true
		end
		
		return false
end


function GuiCollisionService.createCollisionGroup()
	local collisionDetected = Instance.new("BindableEvent")

	local self = setmetatable({
		ColliderTouched = collisionDetected.Event
	}, GuiCollisionService)

	self.colliders = {}
	self.hitters = {}
	self.hierarchy = false 

	game:GetService("RunService").RenderStepped:Connect(function(dt)
		for _, hitter in ipairs(self.hitters) do
			local res = check(hitter, self.colliders, self.hierarchy)
			
			if res then
				local bin = {}

				for i, v in ipairs(res) do
					if table.find(bin, v) then
						table.remove(res, i)
					else
						table.insert(bin, v)
					end
				end

				hitter.i.CollidersTouched:Fire(res)
				hitter.i.Colliding.Value = true
				return
			else
				hitter.i.Colliding.Value = false
			end

			hitter.i.Colliding:GetPropertyChangedSignal("Value"):Connect(function()
				if not hitter.i.Colliding.Value then
					hitter.i.OnCollisionEnded:Fire()
					return
				end
			end)
		end		
	end)

	return self
end

function GuiCollisionService:setZIndexHierarchy(bool: boolean)
	assert(typeof(bool) == "boolean", "argument must be a boolean")
	
	self.hierarchy = true
end

function GuiCollisionService:addHitter(instance, tweens: table)
	assert(typeof(instance) == "Instance", "argument must be an instance")
	assert(typeof(tweens) == "table", "argument must be a table")

	local be = Instance.new("BindableEvent")
	be.Name = "CollidersTouched"
	be.Parent = instance

	local be2 = be:Clone()
	be2.Name = "OnCollisionEnded"
	be2.Parent = instance

	local is = Instance.new("BoolValue")
	is.Name = "Colliding"
	is.Value = false
	is.Parent = instance

	table.insert(self.hitters, { i = instance, t = tweens })
	
	return { index = #self.hitters, ["instance"] = instance }
end

function GuiCollisionService:updateHitter(i: number, instance, tweens: table)
	assert(typeof(i) == "number", "argument must be a table")
	assert(typeof(instance) == "Instance", "argument must be an instance")
	assert(typeof(tweens) == "table", "argument must be a table")
	
	self.hitters[i] = { i = instance, t = tweens or {} }
	
	return { index = i, instance = self.hitters[i].i } 
end

function GuiCollisionService:getHitter(index)
	return self.hitters[index].i
end

function GuiCollisionService:getHitterTweens(index)
	return self.hitters[index].t
end

function GuiCollisionService:getHitters()
	local res = {}

	for _, v in ipairs(self.hitters) do
		table.insert(res, v.i)
	end

	return res
end

function GuiCollisionService:removeHitter(index)
	table.remove(self.hitters, index)
end

function GuiCollisionService:addCollider(instance, t: boolean)
	assert(typeof(instance) == "Instance", "argument must be an instance")
	assert(typeof(t) == "boolean", "argument must be a boolean")

	if not self.colliders then
		self.colliders = {}
	end
	
	if t then
		table.insert(self.colliders, { i = instance, solid = true })
	else
		table.insert(self.colliders, { i = instance })
	end
	
	return { index = #self.colliders, ["instance"] = instance, solid = t }
end

function GuiCollisionService:updateCollider(i: number, instance, t: boolean)
	assert(typeof(i) == "number", "argument must be a table")
	assert(typeof(instance) == "Instance", "argument must be an instance")
	assert(typeof(t) == "boolean", "argument must be a boolean")

	self.colliders[i] = { ["i"] = instance, solid = t }

	return { index = i, instance = self.colliders[i].i, self.colliders[i].solid } 
end

function GuiCollisionService:getColliders()
	local res = {}

	for _, v in ipairs(self.colliders) do
		table.insert(res, v.i)
	end

	return res
end

function GuiCollisionService:removeCollider(index)
	table.remove(self.colliders, index)
end

return GuiCollisionService