So I want to make a coin spawn randomizer with some effects and stuff, making it so I can add as much zones as i can without changing the code. The code works but only works on one zone. If you can help me make the code so it works on both zones. Code is below.
wait(1)
local tweenservice = game:GetService("TweenService")
local tweeninfo2 = TweenInfo.new(0.5)
local tweeninfo1 = TweenInfo.new(1)
local spawnables = game.ReplicatedStorage.Spawnables
local num1 = 30 -- Amount that can be spawned in
local currency = "Visors" -- Currency given when visor is collected
for i,v in pairs(spawnables:GetChildren()) do
local spawnzone = workspace:FindFirstChild("Spawnables"):FindFirstChild(v.Name)
local spawnlimit = spawnzone:FindFirstChild("Spawned")
local currencygiven = v:FindFirstChild("Value").Value
print("loading ".. spawnzone.Name)
while spawnlimit.Value < num1 do
deb = true
local cloned = v:Clone()
local creationtween = tweenservice:Create(cloned,tweeninfo2,{Transparency=0})
cloned.Parent = spawnzone
cloned.CFrame = spawnzone.CFrame * CFrame.new(math.random(-spawnzone.Size.X/2, spawnzone.Size.X/2),spawnzone.Size.Y,math.random(-spawnzone.Size.X/2, spawnzone.Size.X/2))
creationtween:Play()
cloned:FindFirstChild("1").Enabled = true
spawnlimit.Value += 1
if spawnlimit.Value > 25 then
print("Too many visors")
else
print("Spawned visor for ".. spawnzone.Name)
end
cloned.Touched:Connect(function(hit)
local collectedvalue = cloned:FindFirstChild("Collected")
if collectedvalue.Value == false then
local plr = game.Players:FindFirstChild(hit.Parent.Name)
local leaderstats = plr:FindFirstChild("leaderstats")
local points = leaderstats:FindFirstChild(currency)
local removaltween = tweenservice:Create(cloned,tweeninfo1,{Transparency=1})
print(hit.Parent.Name.." collected a visor from ".. spawnzone.Name )
collectedvalue.Value = true
cloned:FindFirstChild("2").Enabled = true
cloned:FindFirstChild("1"):Destroy()
points.Value += currencygiven
spawnlimit.Value -= 1
removaltween:Play()
wait(1)
cloned:FindFirstChild("2").Enabled = false
wait(1)
cloned:Destroy()
end
end)
wait(2)
end
end
I’m thinking the i,v pairs aint working in this case. I’ve tried even using print function to see if both zones would get registered but only one gets registered.
Any help would be appreciated.
Script is up to date.
So, do you want to find all possible zones that has v’s name (exactly v’s name), or do you want zones that would see if v’s name is inside of it’s name?
Firstly, it’s FindFirstChild. It’s going to get the very first child that it finds in the table that meets those conditions (and because there’s two instances with the same exact name, they won’t be able to randomize the two). So what you should’ve done is make another i,v pairs loop for the folder of zones, so that the coins would spawn dedicating to the zone.
Unless you want it randomized to be put in either zone, you can also do:
local zoneToPick = math.random(1, #workspace:FindFirstChild("Spawnables"):GetChildren)
And use the zoneToPick (returns as a number) to find that zone in the folder. Something like this:
local zoneFolder = workspace:FindFirstChild("Spawnables"):GetChildren()
local rZones = math.random(1, #zoneFolder)
local zTP = zoneFolder[rZones]
To put it in your code, it could look something like this:
wait(1)
local tweenservice = game:GetService("TweenService")
local tweeninfo2 = TweenInfo.new(0.5)
local tweeninfo1 = TweenInfo.new(1)
local spawnables = game.ReplicatedStorage.Spawnables
local num1 = 30 -- Amount that can be spawned in
local currency = "Visors" -- Currency given when visor is collected
for i,v in pairs(spawnables:GetChildren()) do
local spawnzone = workspace:FindFirstChild("Spawnables"):GetChildren()
local rZones = math.random(1, #spawnzone)
local zTP = spawnzone[rZones]
local spawnlimit = zTP:FindFirstChild("Spawned")
local currencygiven = v:FindFirstChild("Value").Value
print("loading ".. spawnzone.Name)
while spawnlimit.Value < num1 do
deb = true
local cloned = v:Clone()
local creationtween = tweenservice:Create(cloned,tweeninfo2,{Transparency=0})
cloned.Parent = zTP
cloned.CFrame = spawnzone.CFrame * CFrame.new(math.random(-spawnzone.Size.X/2, spawnzone.Size.X/2),spawnzone.Size.Y,math.random(-spawnzone.Size.X/2, spawnzone.Size.X/2))
creationtween:Play()
cloned:FindFirstChild("1").Enabled = true
spawnlimit.Value += 1
if spawnlimit.Value > 25 then
print("Too many visors")
else
print("Spawned visor for ".. spawnzone.Name)
end
cloned.Touched:Connect(function(hit)
local collectedvalue = cloned:FindFirstChild("Collected")
if collectedvalue.Value == false then
local plr = game.Players:FindFirstChild(hit.Parent.Name)
local leaderstats = plr:FindFirstChild("leaderstats")
local points = leaderstats:FindFirstChild(currency)
local removaltween = tweenservice:Create(cloned,tweeninfo1,{Transparency=1})
print(hit.Parent.Name.." collected a visor from ".. spawnzone.Name )
collectedvalue.Value = true
cloned:FindFirstChild("2").Enabled = true
cloned:FindFirstChild("1"):Destroy()
points.Value += currencygiven
spawnlimit.Value -= 1
removaltween:Play()
wait(1)
cloned:FindFirstChild("2").Enabled = false
wait(1)
cloned:Destroy()
end
end)
wait(2)
end
end
Each iteration in the :GetChildren() table is immediately yielded by your while spawnlimit.Value < num1 loop.
You would need to use task.spawn(), or coroutine's, to make your code work as is. although I highly recommend rewriting your script to not require an absurd amount of threads in order to function as intended.
I don’t really see the problem with that, I think it’s not allowing it to find the instance? Because, is there an instanced inside of the spawnzone that has “Spawned” in it? If there is, you should do a WaitForChild.
If you could, can you explain what this would do as an example? I’m interested too and might need to implement this into some of my future codes as well.
OH WAIT WAIT, no no. Change the spawnzone to zTP. Because right now it’s pulling a value from a table. I believe
local spawnlimit = spawnzone:WaitForChild("Spawned") -- because spawnzone is a table, we're literally pulling a value that's not inside of this table.
-- instead it should've been:
local spawnlimit = zTR:WaitForChild("Spawned") -- since this is the actual instance with the limit
for i = 1, 10 do
while true do
print (i)
task.wait (i * 0.10)
end
end
I want it to continuously print out the numbers from 1 to 10, but the first while true loop immediately yields the thread, making it so only “1” is printed forever.
However, as soon as I implement task.spawn, or coroutine.wrap, the script works as I want it to.
for i = 1, 10 do
task.spawn (function ()
while true do
print (i)
task.wait (i * 0.10)
end
end)
end
for i = 1, 10 do
coroutine.wrap (function ()
while true do
print (i)
task.wait (i * 0.10)
end
end)()
end
Different script, but the concept still applies to the problem presented in this post.
That’s actually useful in some scenarios, making it more easier and faster to code, but then what’s the difference between task.spawn and corotine.wrap?
At the surface, there really isn’t a difference between the two. Personally, I always use task.spawn when I need to solve a problem that requires multi-threading. However, coroutine comes with some features that allow more control over the thread.
It’s possible to yield a thread within the coroutine, or completely terminate the thread entirely. If you need this functionality - use coroutine. If you don’t care / don’t need it, then task.spawn the simpler solution.