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
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")
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.