Help with cloning ScreenGui

I am trying to create a new trucking system for my driving game. I have managed to get the pick up and delivery aspects of the system working, but I have noticed a bug in the game. When a player goes to the pick up and drop off points multiple times, the script controlling the drop off and pick up points clones the gui multiple times.

Here is a video of the issue:

When I go to the pick up point and the drop off point the first time, it works fine, however when i go around a second time, the scripts for both the pick up and the drop off point clone the GUI twice. Each time I go to the pick up and the drop off point, the script clones the GUI an additional time (example: the third time I go around to the pick up point, the script clones the GUI three times).

I have tried looking on the devforum for any topics relating to this issue, however I was unable to find anything.

Here are the scripts for the pick up and drop off points.
Pick Up Point:

hub = script.Parent.Parent.Parent.Parent
prompt = script.Parent.ProximityPrompt
prompt.ObjectText = hub.Name
debounce = script.Parent.Debounce

script.Parent.Touched:Connect(function(hit)
	if hit.ClassName == "VehicleSeat" and debounce.Value == false then
		debounce.Value = true
		local truck = hit.Parent
		local player = game.Players:GetPlayerFromCharacter(truck.DriveSeat.Occupant.Parent)
		if player.TeamColor == BrickColor.new("Black") then
			local trailer = truck:WaitForChild("Trailer", 2)	
			if trailer then
				local trailerType = trailer:WaitForChild("TrailerType", 2)
				prompt.Triggered:Connect(function(player)
					local gui = script.Parent.PickUpGUI:Clone()
					gui.Parent = player.PlayerGui
					gui.Frame.TerminalName.Text = hub.Name
					gui.PickUpPoint.Value = script.Parent
					local cargoType = gui.CargoType
					local amount = gui.Amount
					
					-- Cargo Types
					
					local function food()
						cargoType.Value = "Food"
						gui.Frame.Cargo.CargoType.Text = cargoType.Value
						amount.Value = "50"
						gui.Frame.Cargo.Amount.Text = "50 Units"
					end
					
					local function petrol()
						cargoType.Value = "Petrol"
						gui.Frame.Cargo.CargoType.Text = cargoType.Value
						amount.Value = "50"
						gui.Frame.Cargo.Amount.Text = "50 Units"
					end
					
					if trailerType.Value == "BoxTrailer" then
						food()
					elseif trailerType.Value == "Tanker" then
						petrol()
					end
					gui.Frame.Buttons.Cancel.MouseButton1Click:Connect(function()
						gui:Destroy()
						if debounce.Value == true then
							wait(10)
							debounce.Value = false
						end
					end)
				end)
			end
		end
	end
end)

script.Parent.PickUp.OnServerEvent:Connect(function(player, cargoType, Amount, pickUpGui)
	local gui = player.PlayerGui["A-Chassis Interface"].TruckLoad
	local truck = player.PlayerGui["A-Chassis Interface"].Car.Value
	gui[cargoType].Amount.Text = Amount.. " Units"
	gui[cargoType].Visible = true
	local cargo = Instance.new("IntValue")
	cargo.Name = cargoType
	cargo.Value = Amount
	cargo.Parent = truck.Trailer.Cargo
	print("Successfully Picked Up Cargo")
	pickUpGui:Destroy()
	if debounce.Value == true then
		wait(10)
		debounce.Value = false
	end
end)

Drop Off Point:

hub = script.Parent.Parent
prompt = script.Parent.ProximityPrompt
prompt.ObjectText = hub.DeliveryPointName.Value
debounce = script.Parent.Debounce

script.Parent.Touched:Connect(function(hit)
	if hit.ClassName == "VehicleSeat" and debounce.Value == false then
		debounce.Value = true
		local truck = hit.Parent
		local player = game.Players:GetPlayerFromCharacter(truck.DriveSeat.Occupant.Parent)
		if player.TeamColor == BrickColor.new("Black") then
			local trailer = truck:WaitForChild("Trailer", 2)
			if trailer then
				local trailerType = trailer:WaitForChild("TrailerType", 2)
				prompt.Triggered:Connect(function(player)
					local cargoType = script.Parent.CargoType
					local cargo = trailer.Cargo:FindFirstChild(cargoType.Value)
					if cargo then
						local gui = script.Parent.DropOffGUI:Clone()
						gui.Parent = player.PlayerGui
						gui.Frame.DropOffPoint.Text = hub.DeliveryPointName.Value
						gui.DropOffPoint.Value = script.Parent
						local amount = gui.Amount
						amount.Value = cargo.Value
						gui.Frame.Cargo.CargoType.Text = cargo.Name
						gui.Frame.Cargo.Amount.Text = amount.Value.." Units"
						print("Player has a compatible cargo type")
						gui.Frame.Buttons.Cancel.MouseButton1Click:Connect(function()
							gui:Destroy()
							if debounce.Value == true then
								wait(10)
								debounce.Value = false
							end
						end)
					elseif not cargo then
						local gui = script.Parent.IncompatibleCargoGUI:Clone()
						gui.Parent = player.PlayerGui
						gui.Frame.DropOffPoint.Text = hub.DeliveryPointName.Value
						gui.Frame.Buttons.Cancel.MouseButton1Click:Connect(function()
							gui:Destroy()
							if debounce.Value == true then
								wait(10)
								debounce.Value = false
							end
						end)
					end
				end)
			end
		end
	end
end)

script.Parent.DropOff.OnServerEvent:Connect(function(player, dropOffGui)
	local gui = player.PlayerGui["A-Chassis Interface"].TruckLoad
	local cargoType = script.Parent.CargoType
	gui[cargoType.Value].Amount.Text = ""
	gui[cargoType.Value].Visible = false
	local truck = player.PlayerGui["A-Chassis Interface"].Car.Value
	local cargo = truck.Trailer.Cargo:FindFirstChild(cargoType.Value)
	cargo:Destroy()
	print("Successfully Dropped Off Cargo")
	dropOffGui:Destroy()
	if debounce.Value == true then
		wait(10)
		debounce.Value = false
	end
end)

(Both of these are server scripts)
If anyone would be able to help it would be greatly appreciated.

EDIT: I’ve also noticed that everything that happens when the proximity prompt is triggered is repeated multiple times.

2 Likes

I would used Humanoid.Seated

-- // EXAMPLE:

Player.Character.Humanoid.Seated:Connect(function(Active, Seat)
  if Active then
    if Seat:IsA('VehicleSeat') then
      -- OTHER CODE--
    end
  end
end)
1 Like

The issue is because every time you loop around with the truck you are creating a loop in the script.
It will continue to do this every time you loop around. The solution is to implement a debounce, so the script runs once.

Another way to prevent duplication is to utilize :FindFirstChild().

Example

if game.Players.LocalPlayer.PlayerGui:FindFirstChild("SomeUI") then return end

or

if game.Players.LocalPlayer.PlayerGui:FindFirstChild("SomeUI") == nil then
-- do your stff
end
1 Like

Good Evening All,
I managed to solve the problem by removing the touched event. All the code that is executed when the proximity prompt was triggered was repeated each time I triggered it. When I got rid of the touched event, the proximity prompt acted normal each time I activated it.
Thank you to all who helped!

Tekkie2

1 Like