Problem making drawers open in local script

I have this local script that goes in local player scripts, it goes in workspace, looks for every model named drawers, and in those, it creates a click detector for each interactive part in a drawer. Then, it must connect those click detectors to functions that open each drawer.

The script works fine if you open each drawer very slowly individually, but if you try to open several at the same time or click random ones like crazy, instead of opening and closing normally, they start doing things like going way back into the drawer thingy, or way too forward and floating.

for n,drawers in pairs(workspace:GetChildren()) do
	if drawers.Name == "drawers" then
		local doorOpen = false
		local changingState = false
		local sound = drawers.Dresser.dresser_top.Sound

		for i,v in pairs(drawers:GetDescendants()) do
			if v.Name == "interactive" then
				local selection1 = game.Lighting.interactable.SelectionBox1:Clone()
				local selection2 = game.Lighting.interactable.SelectionBox2:Clone()
				selection1.Parent = v
				selection2.Parent = v
				selection1.Adornee = v
				selection2.Adornee = v
				local clickdetector = Instance.new("ClickDetector")
				clickdetector.Parent = v
				local clickdetectorparent = Instance.new("ObjectValue")
				clickdetectorparent.Name = "clickdetectorparent"
				clickdetectorparent.Value = v
				clickdetectorparent.Parent = clickdetector
				clickdetector.MouseClick:Connect(function(player, part)
					clickdetector.Parent = workspace.important
					if doorOpen == true and changingState == false then
						changingState = true
						sound:Play()
						clickdetector.clickdetectorparent.Value.Parent:SetPrimaryPartCFrame(clickdetector.clickdetectorparent.Value.Parent.PrimaryPart.CFrame * CFrame.new(0, 0, 3.2))
						changingState = false
						doorOpen = false
					elseif changingState == false then
						changingState = true
						sound:Play()
						clickdetector.clickdetectorparent.Value.Parent:SetPrimaryPartCFrame(clickdetector.clickdetectorparent.Value.Parent.PrimaryPart.CFrame * CFrame.new(0, 0, -3.2))
						changingState = false
						doorOpen = true
					end
					wait(1)
					clickdetector.Parent = clickdetector.clickdetectorparent.Value
				end)
			end
		end
	end
end```
1 Like

Most likely because they all share the changingState variable, when you click on multiple drawers at the same time, they all try to modify this shared variable, which probably causes said behavior.

Try moving the variable down for each seperate drawer:

for n,drawers in pairs(workspace:GetChildren()) do
    if drawers.Name == "drawers" then
        local doorOpen = false
        local sound = drawers.Dresser.dresser_top.Sound

        for i,v in pairs(drawers:GetDescendants()) do
            if v.Name == "interactive" then
                local changingState = false  -- Move this line here
                local selection1 = game.Lighting.interactable.SelectionBox1:Clone()
                local selection2 = game.Lighting.interactable.SelectionBox2:Clone()
                selection1.Parent = v
                selection2.Parent = v
                selection1.Adornee = v
                selection2.Adornee = v
                local clickdetector = Instance.new("ClickDetector")
                clickdetector.Parent = v
                local clickdetectorparent = Instance.new("ObjectValue")
                clickdetectorparent.Name = "clickdetectorparent"
                clickdetectorparent.Value = v
                clickdetectorparent.Parent = clickdetector
                clickdetector.MouseClick:Connect(function(player, part)
                    clickdetector.Parent = workspace.important
                    if doorOpen == true and changingState == false then
                        changingState = true
                        sound:Play()
                        clickdetector.clickdetectorparent.Value.Parent:SetPrimaryPartCFrame(clickdetector.clickdetectorparent.Value.Parent.PrimaryPart.CFrame * CFrame.new(0, 0, 3.2))
                        changingState = false
                        doorOpen = false
                    elseif changingState == false then
                        changingState = true
                        sound:Play()
                        clickdetector.clickdetectorparent.Value.Parent:SetPrimaryPartCFrame(clickdetector.clickdetectorparent.Value.Parent.PrimaryPart.CFrame * CFrame.new(0, 0, -3.2))
                        changingState = false
                        doorOpen = true
                    end
                    wait(1)
                    clickdetector.Parent = clickdetector.clickdetectorparent.Value
                end)
            end
        end
    end
end
2 Likes

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