Help with drop script

I’m making a script for a series of ‘baskets’ which spawn items. I am using a debounce to make sure the items do not respawn unless the player has picked up the item. I am using a boolvalue to do this, as the tool to pick up the item turns the boolvalue true. This in turn turns the debounce false, allowing the script to repeat. It also destroys the item. The script runs, and the item is destroyed when the player picks it up, but the script doesn’t repeat. I put a print(debounce) in the script which came out as ‘false’ then ‘true’, but didn’t print false again. Any help would be much appreciated.

local Basket1 = game.Workspace.Basket1
local Basket2 = game.Workspace.Basket2

local repStor = game:GetService("ReplicatedStorage")
local Item1 = repStor.Item1

local debounce = false

local newThread = coroutine.create(function(debounce)
	while true do
	print(debounce)
	   if debounce then return 
	    else
	        debounce = true
	        local newItem1 = Item1:Clone()
	        newItem1.Parent = Basket1
	        newItem1.CFrame = Basket1.CFrame
	        newItem1.Anchored = true
	 
	 		wait(5)
	
			local Check = Instance.new("BoolValue")
			Check.Name = "Check"
			Check.Parent = Item1
			Check.Value = false
	
			Check.Changed:Connect(function()
				if Check.Value == true then 
					debounce = false  
					Item1:Destroy() 
				end
			end)
		end
	end
end)

coroutine.resume(newThread, debounce)

*This is just an excerpt of the script designed to illustrate my problem.

2 Likes

You can’t use two different objects as same name meaning the debounce, try to rename the first debounce to something another. I don’t see a problem in this script this is what I got.

1 Like

Could you expand on that? Debounce usually works by changing its value at various points in the script, making sure the script doesn’t repeat itself until the various conditions are met.

Your issue is that it doesn’t repeat itself as you’re wanting it to but fires once?

1 Like

Yes, essentially. It fires once, but doesn’t fire again because debounce isn’t changed to false.

I believe you don’t need the debounce here; just listen for the .Changed event using :Wait, which yields until a property is changed.

local newThread = coroutine.create(function()
	while true do
	    local newItem1 = Item1:Clone()
	    newItem1.Parent = Basket1
	    newItem1.CFrame = Basket1.CFrame
	    newItem1.Anchored = true
	 
	    wait(5)
	
        local Check = Instance.new("BoolValue")
		Check.Name = "Check"
		Check.Parent = Item1
		Check.Value = false
	
		Check.Changed:Wait()
		newItem1:Destroy() 
	end
end)

coroutine.resume(newThread)
1 Like

A more relevant answer could be that you return when the debounce is true, causing the entire loop to break. Just check if the debounce is not true, and make sure to add some sort of yield to maintain the loop.

local newThread = coroutine.create(function(debounce)
  while true do
     if not debounce then
        debounce = true
        local newItem1 = Item1:Clone()
        newItem1.Parent = Basket1
        newItem1.CFrame = Basket1.CFrame
        newItem1.Anchored = true
    
        wait(5)
   
   		local Check = Instance.new("BoolValue")
   		Check.Name = "Check"
   		Check.Parent = Item1
   		Check.Value = false
   
   		Check.Changed:Connect(function()
   			if Check.Value == true then 
   				debounce = false  
   				newItem1:Destroy() 
   			end
   		end)
   	end
    wait()
   end
end)

coroutine.resume(newThread, debounce)
1 Like

Then your code is terribly inefficient considering you can just do this:

function SpawnItem()
    local newItem1 = Item1:Clone()
    newItem1.CFrame = Basket1.CFrame
    newItem1.Anchored = true
    
    local Check = Instance.new("BoolValue")
    Check.Name = "Check"
    Check.Value = false
    Check.Parent = Item1
    
    newItem1.Parent = Basket1 -- Remember to set the properties **before** you parent the instance!
    
    Check:GetPropertyChangedEvent("Value"):Connect(function()
        if Check.Value then 
            newItem1:Destroy() -- changed Item1 to newItem1 as I don't think you meant to delete the Item1 object
            SpawnItem() -- spawning a new basket when the previous basket gets destroyed
        end
    end)
end

SpawnItem()
2 Likes

Thanks for the reply. In this example wouldn’t the basket just continue producing items, and not only when the item is picked up?

This makes sense. Would this kind of thing be generally more efficient compared with coroutines, even if I have multiple threads?