I have a problem where if I’m trying to only click on the current CanvasGroup using InputBegan, it registers input on other CanvasGroups under the current one. Sorry if that didn’t make sense. Here is a video of what is happening.
I don’t want other CanvasGroups getting input. Here is the script:
local systemContainer = game.Players.LocalPlayer.PlayerGui:WaitForChild("SystemContainer")
local systemWindows = systemContainer.SystemWindows
local function bringToFront(canvasGroup)
local highestZIndex = 0
for _, window in ipairs(systemWindows:GetChildren()) do
local zIndex = window.ZIndex
if zIndex > highestZIndex then
highestZIndex = zIndex
end
end
if canvasGroup.ZIndex == highestZIndex then
return
end
for _, window in ipairs(systemWindows:GetChildren()) do
if window ~= canvasGroup then
window.ZIndex -= 1
end
end
canvasGroup.ZIndex = highestZIndex
end
for _, window in ipairs(systemWindows:GetChildren()) do
window.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
bringToFront(window)
end
end)
end
systemWindows.ChildAdded:Connect(function(newWindow)
newWindow.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
bringToFront(newWindow)
end
end)
local highestZIndex = 0
for _, window in ipairs(systemWindows:GetChildren()) do
local zIndex = window.ZIndex
if zIndex > highestZIndex then
highestZIndex = zIndex
end
end
newWindow.ZIndex = highestZIndex + 1
end)
If you need clarification, I will be happy to do so.
When a window is clicked, instead of directly using the BringToFront function, check if the clicked window has the highest Z index, and then use the function.
for _, window in ipairs(systemWindows:GetChildren()) do
window.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if window.ZIndex == #systemWindows:GetChildren() then
bringToFront(window)
end
end
end)
end
Just make a function that iterates over all of the existing windows and return the highest Z index one, then check if the clicked one is the same as the returned one. Would be something like:
local windowsLocation = exampleLocation
function GetHighestZIndexWindow(Location)
local Children = Location:GetChildren()
local HighestIndex = 0
local HighestZWindow = nil
for i,v in pairs(Children) do
if v.ZIndex > HighestIndex then
HighestIndex = v.ZIndex
HighestZWindow = v
end
end
return HighestZWindow
end
(i wrote this on mobile, not sure if i missed something )
local systemContainer = game.Players.LocalPlayer.PlayerGui:WaitForChild("SystemContainer")
local windowsLocation = game.Players.LocalPlayer.PlayerGui:WaitForChild("SystemContainer").SystemWindows
local systemWindows = systemContainer.SystemWindows
--Function to keep the windows in the right order
function GetHighestZIndexWindow(Location)
local Children = Location:GetChildren()
local HighestIndex = 0
local HighestZWindow = nil
for i,v in pairs(Children) do
if v.ZIndex > HighestIndex then
HighestIndex = v.ZIndex
HighestZWindow = v
end
end
return HighestZWindow
end
-- Function to bring a CanvasGroup to the front
local function bringToFront(canvasGroup)
local highestZIndex = 0
-- Find the highest ZIndex among all CanvasGroups
for _, window in ipairs(systemWindows:GetChildren()) do
local zIndex = window.ZIndex
if zIndex > highestZIndex then
highestZIndex = zIndex
end
end
-- If the CanvasGroup already has the highest ZIndex, do nothing
if canvasGroup.ZIndex == highestZIndex then
return
end
-- Update ZIndex for all CanvasGroups
for _, window in ipairs(systemWindows:GetChildren()) do
if window ~= canvasGroup then
window.ZIndex -= 1
end
end
-- Bring the clicked CanvasGroup to the front
canvasGroup.ZIndex = highestZIndex
end
-- Connect input began events for existing CanvasGroups
for _, window in ipairs(systemWindows:GetChildren()) do
window.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
local Result = GetHighestZIndexWindow(windowsLocation)
print(window.ZIndex)
if Result == window then
bringToFront(window)
print("hi")
end
end
end)
end
-- Connect a function to handle new CanvasGroups being added
systemWindows.ChildAdded:Connect(function(newWindow)
newWindow.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
bringToFront(newWindow)
end
end)
-- When a new window is added, set its ZIndex to be on top
local highestZIndex = 0
for _, window in ipairs(systemWindows:GetChildren()) do
local zIndex = window.ZIndex
if zIndex > highestZIndex then
highestZIndex = zIndex
end
end
newWindow.ZIndex = highestZIndex + 1
end)
The output prints “hi”, but the bringToFront() function does not work.
Try to not use the bringToFront function if the window is already the highest Z index one:
for _, window in ipairs(systemWindows:GetChildren()) do
window.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
local Result = GetHighestZIndexWindow(windowsLocation)
if Result == window then
print("didnt bring to front because its already the highest one")
else
bringToFront(window)
end
end
end)
end
Oh hi, I didn’t get the previous reply’s notification. Unfortunately I don’t think I have a solution for you, I barely work with UI. Good luck solving this.
Bumping this topic. If anyone has a solution, I would much appreciate it. I had an idea to fix this, but I don’t know if it would work. My idea is to check what window is on top, and then if another window was clicked behind it, cancel that click so only the top window registers it, because for some reason UserInputService registers clicks through frames.
TLDR: My problem is UserInputService registers clicks through two frames.