Item removal from world

I have a script that controls loot drops in the game. If the loot is touched, the gold is collected, and the item is destroyed.

However… sometimes the item does not destroy. I tried a 1 second timer and every so often something still stays on the ground.

Does anyone have any ideas on a fail safe that will delete the item if it gets left behind?

local sound = script.Parent.Gem -- Defining the sound in the same script

local touchConnection -- Making a connection so we can stop the part detecting touches

touchConnection = script.Parent.Touched:Connect(function(hit) -- "hit" is the BasePart that touched "script.Parent". This is a variable
	if hit.Parent:FindFirstChild("Humanoid") then -- Seeing if an object called "Humanoid" is a child of the parent the object touched
		local player = game.Players:GetPlayerFromCharacter(hit.Parent) -- Getting the player if the character is found
		if hit.Parent.Humanoid.Health > 0  then -- Checking if the player is dead

			touchConnection:Disconnect() -- Disconnecting the touched event so it doesn't fire again

			sound:Play() -- Playing the sound

			wait(sound.TimeLength) -- TimeLength is how long the sound is. We're waiting this long

			player.leaderstats.Gold.Value = player.leaderstats.Gold.Value + script.Parent.Gold.Value -- Increaseing the gold of the player
			wait(1)
			script.Parent:Destroy() -- Destroy() is the new function to destroy, Remove() was deprecated
		end
	end
end)
1 Like

This is likely caused by how early you’re disconnecting the event. From my testing it would disconnect and then do the next line but it wouldn’t read any further in the script. Try disconnecting before the part gets destroyed, like this:

local sound = script.Parent.Gem

local touchConnection

touchConnection = script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		local player = game.Players:GetPlayerFromCharacter(hit.Parent)
		if hit.Parent.Humanoid.Health > 0  then

			sound:Play() 

			wait(sound.TimeLength)

			player.leaderstats.Gold.Value = player.leaderstats.Gold.Value + script.Parent.Gold.Value
			wait(1)
			touchConnection:Disconnect()
			
			script.Parent:Destroy()
		end
	end
end)

Is this script in every loot that drops? Or is it all in one script?

Anywho, you could use the Debris service-
API reference:

Instead of adding a wait(1) you could just do

local debris = game:GetService(“Debris”)
debris:AddItem(script.Parent,0)

I usually use debris thanthe :Destroy method, but it would depend on the scenario. Mostly I use debris since it wouldn’t yield my code.

Also I did notice your code also disconnected the connection before you destroyed the part. Try destroying, then disconnecting to ensure everything has ran. And to make sure the touched event doesn’t run more than once, just add a debounce variable.

I tried this script, but it will not collect the gold at all. I just run over the top of it and it stays on the ground.

Going to test this method out now, thanks for the suggestion.

I am reading this link, but not sure exactly how to put the debirs line in yet.

Is this correct?

local sound = script.Parent.Gem -- Defining the sound in the same script

local touchConnection -- Making a connection so we can stop the part detecting touches

local debris = game:GetService(“Debris”)

touchConnection = script.Parent.Touched:Connect(function(hit) -- "hit" is the BasePart that touched "script.Parent". This is a variable
	if hit.Parent:FindFirstChild("Humanoid") then -- Seeing if an object called "Humanoid" is a child of the parent the object touched
		local player = game.Players:GetPlayerFromCharacter(hit.Parent) -- Getting the player if the character is found
		if hit.Parent.Humanoid.Health > 0  then -- Checking if the player is dead

			touchConnection:Disconnect() -- Disconnecting the touched event so it doesn't fire again

			sound:Play() -- Playing the sound

			wait(sound.TimeLength) -- TimeLength is how long the sound is. We're waiting this long

			player.leaderstats.Gold.Value = player.leaderstats.Gold.Value + script.Parent.Gold.Value -- Increaseing the gold of the player
			script.Parent:Destroy() -- Destroy() is the new function to destroy, Remove() was deprecated
			debris:AddItem(script.Parent,0)
		end
	end
end)

I will do more testing tomorrow but I think your solution was the winner. This is the script I settled on for the night. I got stuck for hours because I wasn’t paying attention to the sound definition. I am a new scripter so everything takes me freaking forever.

local sound = script.Parent.pickup -- Defining the sound in the same script

local touchConnection -- Making a connection so we can stop the part detecting touches

local debris = game:GetService("Debris")

touchConnection = script.Parent.Touched:Connect(function(hit) -- "hit" is the BasePart that touched "script.Parent". This is a variable
	if hit.Parent:FindFirstChild("Humanoid") then -- Seeing if an object called "Humanoid" is a child of the parent the object touched
		local player = game.Players:GetPlayerFromCharacter(hit.Parent) -- Getting the player if the character is found
		if hit.Parent.Humanoid.Health > 0  then -- Checking if the player is dead

			touchConnection:Disconnect() -- Disconnecting the touched event so it doesn't fire again

			sound:Play() -- Playing the sound

			wait(sound.TimeLength) -- TimeLength is how long the sound is. We're waiting this long

			player.leaderstats.Gold.Value = player.leaderstats.Gold.Value + script.Parent.Gold.Value -- Increaseing the gold of the player

			debris:AddItem(script.Parent,0)

		end
	end
end)

Im going to bed, but if someone could put a debounce in the other script I would GREATLY appreciate it. I started to attempt it and was too tired to make it work.

This script needs a debounce, as it is I can collected the items a bunch of times before they destroy. but I would like to try it out tomorrow and see which one works better.


local sound = script.Parent.Gem

local touchConnection

touchConnection = script.Parent.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") then
		local player = game.Players:GetPlayerFromCharacter(hit.Parent)
		if hit.Parent.Humanoid.Health > 0  then

			sound:Play() 

			wait(sound.TimeLength)

			player.leaderstats.Gold.Value = player.leaderstats.Gold.Value + script.Parent.Gold.Value
			wait(1)
			touchConnection:Disconnect()
			
			script.Parent:Destroy()
		end
	end
end)