Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Random Event then Destory() not working?

So what the code is suppose to do, when there are no more Parts in 'Trunk' then it randomly select a Part from Leaves and remove it, here's the code:

function DLeaves()
	local Leaves = script.Parent:WaitForChild("Leaves"):GetChildren()
	local Trunk = script.Parent:WaitForChild("Trunk"):GetChildren()
	if #Leaves == 0 then
		return;
	end
	
	if #Trunk == 0 then
		Random = math.random(1, #Leaves)
		Random2 = Random
		
		while Random == Random2 do
			Random2 = math.random(1, #Leaves)
			wait()
		end
	Chosen = Leaves[Random]	
	Chosen2 = Leaves[Random2]
	end
	Chosen:Destroy()
	Chosen2:Destroy()
end
 
while true do
	wait(0.5)
	DLeaves()
end

Output: http://prntscr.com/9qk5gy

2 comments

0

Nothing works with it, added output in a prntscr.

0

is return suposed to be break?

2 answers

✓ Accepted answer

In addition to what Spongocardo said:

*while Random == Random2 do will loop forever when #Leaves is 1, since math.random(1, 1) will always return 1. .

*math.random can be called without a second argument (i.e. using math.random(10) will return a random integer from 1 to 10)

*The while true do loop in the bottom will run even if the tree doesn't need to wilt. While this might not be a problem when there's only one tree, it will when you have more.

*In addition, the loop will never stop even if there are no leaves left in the tree.

*This program overall is poorly designed (what if you want to change how many leaves are removed per tick? What if you want to change how the leaves disappear?)

Try this:

-- Load some variables into the script
local Trunk = script.Parent:WaitForChild("Trunk")
local Leaves = script.Parent:WaitForChild("Leaves")
-- Delay between wilting steps
local WILT_DELAY = 0.5
-- Amount of leaves to wilt per step
local WILT_AMOUNT = 2

-- Once called, the leaves on the tree will start to wilt
function Wilt()
	Leaves_Parts = Leaves:GetChildren()
	-- Called whenever a leaf is shed.
	local function ShedLeaf(leaf)
		leaf:Destroy()
	end
	-- Wilts a number of leaves specified by "number"
	local function WiltStep(number)
		-- if there are less than "number" parts left in Leaves, wilt the rest.
		for i = 1, math.min(number, #Leaves_Parts) do
			-- select a random leaf to wilt
			local rand = math.random(#Leaves_Parts)
			ShedLeaf(Leaves_Parts[rand])
			table.remove(Leaves_Parts, rand)
		end
	end
	
	--loops until there are no leaves left
	while #Leaves_Parts > 0 do 
		wait(WILT_DELAY)
		WiltStep(WILT_AMOUNT)
	end
	--print("Wilting Ended")
end

-- Called whenever something is removed from Trunk. When there are no parts left in the trunk, Wilt() is executed.
Trunk.ChildRemoved:connect(function (_)
	local Trunk_Parts = Trunk:GetChildren()
	if #Trunk_Parts == 0 then
		-- print("Wilting...")
		Wilt()
	end
end)

--print("Script Loaded")

2 comments

0

I appreciate what you are saying, and your help too. But I am not very good at coding so please don't criticise me, after all this is a help site.

0

Very good answer, upvoted.

The problem is that if there are parts in the trunk, the Random and Random2 variables will never be assigned, therefore the script would be trying to destroy a nil value. This is why the output says that you're attempting to index 'Chosen', which would be a nil value.

To fix this, you should have the Destroy method(s) inside of the if statement so that the leaves are only destroyed when the number of parts in 'Trunk' equals 0, which will be when the random variables are assigned.


function DLeaves()
    local Leaves = script.Parent:WaitForChild("Leaves"):GetChildren()
    local Trunk = script.Parent:WaitForChild("Trunk"):GetChildren()
    if #Leaves == 0 then
        return;
    end

    if #Trunk == 0 then
        local Random = math.random(1, #Leaves) --It's quicker to access local variables than global ones.
        local Random2 = Random --Same as above.

        while Random == Random2 do
            Random2 = math.random(1, #Leaves) --No need for local before Random2 here since we've already assigned Random2 earlier.
            wait()
        end
        Leaves[Random]:Destroy() --No need to assign a variable here, just do Leaves[Random].
        Leaves[Random2]:Destroy() --Same as above.
    end
end

while true do
    wait(0.5)
    DLeaves()
end


I hope my answer helped you. If it did, be sure to accept it.

This discussion is preserved as it was. New answers, comments, and votes are closed.