Issue with GetGuiObjectsAtPosition on a local server (2plr)

This code seems to work perfectly in singleplayer playtest but when switching to a 2 player test, it’s unable to pickup on certain GUI elements despite them existing? Forgive me if it’s something really obvious, but I cannot wrap my head around this. (The script is for adding a button for each item picked up, and then onclick the player can drop the item)

local plr = game:GetService("Players").LocalPlayer
local inventory = plr:WaitForChild("Inventory")
local plrGui = plr:WaitForChild("PlayerGui")
local gui = plrGui:WaitForChild("InventoryGUI")

local function itemButtonPressed(x: number, y: number)
	hideOtherButtons()
	local buttons = plrGui:GetGuiObjectsAtPosition(x, y - guiInset.Y)
	print(buttons)
	local dropButton = buttons[2].DropButton -- this is where it errors line 74
	local equipButton = buttons[2].EquipButton
	dropButton.Visible = true
	equipButton.Visible = true
	equipButton.MouseButton1Down:Connect(buttonEquip)
	dropButton.MouseButton1Down:Connect(buttonDrop)
end

local function addInteractionWithButton(item)
	if item:IsA("ImageButton") then
		item.MouseButton1Down:Connect(itemButtonPressed)
	end
end

local function weightUpdate(weight)
	gui.TopFrame.WeightLabel.Text = "weight: " ..tostring(weight)
end

gui.TopFrame.Frame.DescendantAdded:Connect(addInteractionWithButton)


3 Likes

It might be just that your inventory isn’t defined, use waitForChild maybe

1 Like

Are you sure the guiObject you are receiving is the StonePick frame? It could be any of those parent frames if they are at that position. If it is the parent frame, then each of those button names would not exist.

1 Like

Sorry, didn’t put variables. I used waitforchild.

1 Like

I’m a bit confused on what you mean, but I had changed the ZIndex for all the gui elements so that the frames would be in order. More confused on why they aren’t getting picked up in the table

1 Like

I just noticed in your output that it says you are indexing TopFrame, so you are selecting a parent frame instead of the frame you are looking for. Instead, I would loop through the array of the GuiObjects at the position to find the button you are looking for.

Just tried looping, works in 1plr playtest but not 2plr playtest. ImageButton not showing up in table. Don’t get how it’s getting the ScreenGui.
Medallz 12|09|2024 |

local function itemButtonPressed(x: number, y: number)
	hideOtherButtons()
	local buttons = plrGui:GetGuiObjectsAtPosition(x, y - guiInset.Y)
	for i, v in pairs(buttons) do
		if not v:IsA("ImageButton") then
			table.remove(buttons, i)
		end
	end
	print(buttons)
	local dropButton = buttons[1].Parent.DropButton
	local equipButton = buttons[1].Parent.EquipButton
	dropButton.Visible = true
	equipButton.Visible = true
	equipButton.MouseButton1Down:Connect(buttonEquip)
	dropButton.MouseButton1Down:Connect(buttonDrop)
end

One thing is that you can’t remove items when looping through them like you have up there, this will cause your loop end early and not remove all necessary frames. However, just check in that loop if the item is a button and check its name and add your connections there, instead of after.

Am I understanding correctly?

local function itemButtonPressed(x: number, y: number)
	hideOtherButtons()
	local buttons = plrGui:GetGuiObjectsAtPosition(x, y - guiInset.Y)
	for i, v in pairs(buttons) do
		if v:FindFirstChildOfClass("ImageButton") then
			v.Parent.EquipButton.MouseButton1Down:Connect(buttonEquip)
			v.Parent.DropButton.MouseButton1Down:Connect(buttonDrop)
			v.Parent.dropButton.Visible = true
			v.Parent.equipButton.Visible = true
		end
	end
	print(buttons)
end

Medalpr 12|09|2024 |
MedalHf 12|09|2024 |

Yes you are understanding this correctly, the code just needs some slight changes:

local function itemButtonPressed(x: number, y: number)
	hideOtherButtons()
	local buttons = plrGui:GetGuiObjectsAtPosition(x, y - guiInset.Y)
	for i, v in ipairs(buttons) do
		if not v:IsA("ImageButton") then
			return
		end
		if v.Name == "dropButton" then
			v.Parent.DropButton.MouseButton1Down:Connect(buttonDrop)
			v.Parent.dropButton.Visible = true
		elseif v.Name == "equipButton" then
			v.Parent.EquipButton.MouseButton1Down:Connect(buttonEquip)
			v.Parent.equipButton.Visible = true
		end
	end
end
1 Like

I think GetGuiObjectsAtPosition doesn’t detect invisible gui elements? drop and equip buttons are no longer being turned visible/connected. 1plr playtest prints gui elements correctly, 2plr playtest prints gui elements only when clicking the Weight textlabel? :sweat_smile:

I also just noticed that those two buttons are TextButtons. Are you sure it is not being detected?

Maybe changing this to

if not v:IsA("TextButton") then

might work

Doesn’t seem to work sadly. Just to be clear, the loop is finding the buttons and then connecting them, ignoring other gui elements?
Text buttons (drop/equip) do not show up when printed beforehand :thinking:
MedalY2 12|09|2024 |

Also, I just realized, why are you connecting to the buttons twice? Like you are connecting to them in itemButtonPressed() and in addInteractionButton().

When the actual item is clicked, the 2 text buttons (drop/equip) are supposed to appear in the item, so you can choose which option.
diagrma

So they appear at once? The reason I ask is because there may be no reason to use GetGuiObjectsAtPosition if you know which buttons are going to show up already.

Yes, both buttons appear. But the item is added upon pickup. If you know how I can get an item variable from addInteractionWithButton() to itemButtonPressed() that would be super helpful as a potential alternative

Will something like this work?

local function itemButtonPressed(button)
	hideOtherButtons()
	local dropButton = button.Parent.DropButton
	local equipButton = button.Parent.EquipButton
	dropButton.Visible = true
	equipButton.Visible = true
	equipButton.MouseButton1Down:Connect(buttonEquip)
	dropButton.MouseButton1Down:Connect(buttonDrop)
end

local function addInteractionWithButton(item)
	if item:IsA("ImageButton") then
		item.MouseButton1Down:Connect(function(x: number, y: number)
			itemButtonPressed(item)
		end)
	end
end
1 Like

awesome, this seems to work. Just have another problem but it’s in another script, I appreciate it, thank you

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.