Placement script continually adding a structure each time

I have a placement system which works fine. The only issue is that every time I place an object, the next time I place that same object 2 are placed instead of 1, then when I place it again 3 are placed, then 4 etc. It seems to be like a kind of (n + 1) sequence. It even subtracts that amount from your inventory. I’m not really sure what’s causing this.

I’ve left out the variables since I didn’t really think it necessary. I’ve also only included the local script since that’s where I believe the issue to be, although if you want the server script then just ask.

while true do
	wait(1)
	for _,structureButton in pairs(ItemList.Trees:GetChildren()) do
		local structurename = structureButton.Name
		if structureButton:IsA("TextButton") and Inventory:FindFirstChild(structurename).Value > 0 then 
		print(Inventory:FindFirstChild(structurename).Value)
			structureButton.MouseButton1Up:Connect(function()
					InventoryGUI.Enabled = false
					PlacingGUI.Enabled = true
					
					local goodtoplace = false
					local placedStructure
		
					if placingStructure == false then 
						placingStructure = true
						local clientStructure = Structures:FindFirstChild(structurename):Clone()
						clientStructure.BrickColor = BrickColor.new("Forest green")
						clientStructure.Material = "Neon"
						clientStructure.Transparency = 0.4
						clientStructure.CanCollide = false
						clientStructure.Parent = game.Workspace
		
						local startingCFrame = CFrame.new(0, -2, 15)
						clientStructure.CFrame = humRoot.CFrame:ToWorldSpace(startingCFrame)
						
						RunService.RenderStepped:Connect(function()
							local mouseRay = mouse.UnitRay
							local castRay = Ray.new(mouseRay.Origin, mouseRay.Direction*1000)
							local ignoreList = {clientStructure, char}
							hit, position = workspace:FindPartOnRayWithIgnoreList(castRay, ignoreList)
							local newCFrame = CFrame.new(position.X, position.Y + yBuildingOffset, position.Z)
							clientStructure.CFrame = newCFrame

							if hit and CollectionService:HasTag(hit, "PlotPart") and (humRoot.Position - clientStructure.Position).Magnitude < MaxDistance then
								clientStructure.BrickColor = BrickColor.new("Forest green")
								goodtoplace = true
								clientStructure.CFrame = CFrame.new(hit.CFrame.x, hit.CFrame.y + clientStructure.Size.y/2, hit.CFrame.z)
								if CollectionService:HasTag(hit, "Occupied") then 
									goodtoplace = false
									clientStructure.BrickColor = BrickColor.new("Crimson")
								else
									goodtoplace = true
									clientStructure.BrickColor = BrickColor.new("Forest green")
								end
							else
								clientStructure.BrickColor = BrickColor.new("Crimson")
								goodtoplace = false
							end
						end)
					UIS.InputBegan:Connect(function(input)
						if input.KeyCode == Enum.KeyCode["C"] then
							if placingStructure == true then
								placingStructure = false
								clientStructure:Destroy()
								InventoryGUI.Enabled = true
								PlacingGUI.Enabled = false
							end
						end
					end)
					
					UIS.InputBegan:Connect(function(input)
						if input.UserInputType == Enum.UserInputType.MouseButton1 then
							if placingStructure == true then
								if goodtoplace == true then
									local StructureCFrame = clientStructure.CFrame
									placedStructure = PlaceStructure:InvokeServer(clientStructure.Name, clientStructure.CFrame, Inventory, hit.Name)
									
									if placedStructure then
										CollectionService:AddTag(hit, "Occupied")
										placingStructure = false
										clientStructure:Destroy()
										InventoryGUI.Enabled = true
										PlacingGUI.Enabled = false
									end
								end
							end
						end
					end)
				end
			end)
		end
	end
	Close.MouseButton1Up:Connect(function()
		InventoryGUI.Enabled = false
		MainGUI.Enabled = true
	end)
end

Here’s a pastebin of the same script if you find it hard to read:
https://pastebin.com/RVVPGXt1

1 Like

Probably because you didn’t disconnect the renderstepped or in input began, so if you run the system again, the previous connection would still be there. Just disconnect the functions and it would be solved:

local SteppedConnection -- Sets the function as a variable
SteppedConnection = RunService.RenderStepped:Connect(function()

end)
local InputBegn -- Sets the function as a variable
InputBegan = UIS.InputBegan:Connect(function(input)

end)

SteppedConnection:Disconnect() -- Disconnects the function
InputBegan:Disconnect() -- Disconnects the function

Once you disconnect it you wouldn’t have duplicate functions.

1 Like

Interesting. I didn’t really know that was a thing. So should I disconnect when the InvokeServer fires?

No, you don’t need to disconnect that, you cant even disconnect that.

1 Like

No I mean should I disconnect UIS and RunService directly after InvokeServer. Sorry for the lack of clarity.

If that’s something that places the object down then yes, disconnect after that.

1 Like