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

Help with CFrame Loops?

Well I have a script that gets the children from a "Dummys" model, yes I know it should be spell "dummies" this is the internet, well past that bit, it should "spawn" a "dummy" at every "spawn" but no at the same one, that bit works, it just stops around 4 "dummys" left no error or anything.

wait(3)
for _,v in pairs (game.Workspace.Dummys:GetChildren()) do
	wait(0.3)
	local RandomSpawn=game.Workspace.Spawns:children''[math.random(1,#game.Workspace.Spawns:children'')]
		if RandomSpawn:FindFirstChild("Used") then
		if not RandomSpawn:FindFirstChild("Used").Value then
			RandomSpawn:findFirstChild("Used").Value = true
			v.Torso.CFrame = CFrame.new(RandomSpawn.Position) + Vector3.new(0, 1, 0)
			wait()
		end
	end
end

Is my main script and only spawns is like Game/Workspace/Spawns

"Dummys" are Game/Workspace/Dummys ----Gif of it

2 answers

✓ Accepted answer

Here's a cleaned up version of what you wrote (better names, spacing, style) (using :children'' is absurd) that does exactly what you did:

wait(3)
local spawns = game.Workspace.Spawns:GetChildren()

for _, dummy in pairs (game.Workspace.Dummys:GetChildren()) do
	wait(0.3)
	local RandomSpawn = spawns[math.random(1, #spawns)]
	if RandomSpawn:FindFirstChild("Used") then
		if not RandomSpawn.Used.Value then
			RandomSpawn.Used.Value = true
			dummy.Torso.CFrame = CFrame.new(RandomSpawn.Position)
				+ Vector3.new(0, 1, 0)
		end
	end
	wait()
end

Remark What happens when the spawn you picked randomly has already been picked? You don't move the dummy; the dummy remains where it is, and you move onto the next one.

You instead ought to continue trying until you manage to place it. A repeat until loop is a brief way to accomplish that.

wait(3)
local spawns = game.Workspace.Spawns:GetChildren()
for _, dummy in pairs (game.Workspace.Dummys:GetChildren()) do
	wait(0.3)
	local RandomSpawn -- Declare RandomSpawn's scope.
	repeat
		-- Maybe this one will work?
		RandomSpawn = spawns[math.random(1, #spawns)]
		wait() -- Just in case you run out, instead of crashing,
		-- it will just stop placing.
	until RandomSpawn:FindFirstChild("Used") and not RandomSpawn.UsedValue
	-- RandomSpawn has not yet been used, so use it now
	RandomSpawn.Used.Value = true
	dummy.Torso.CFrame = CFrame.new(RandomSpawn.Position)
		+ Vector3.new(0, 1, 0)
end

Alternatively, instead of using Used, you could just remove random objects from your list of spawns, which is much more straightforward:

wait(3)
local spawns = game.Workspace.Spawns:GetChildren()

for _, dummy in pairs (game.Workspace.Dummys:GetChildren()) do
	wait(0.3)
	local RandomSpawn = table.remove(spawns, math.random(1,# spawns))
	-- RandomSpawn has not yet been used -- and is now gone from the list
	-- for future dummies
	dummy.Torso.CFrame = CFrame.new(RandomSpawn.Position)
		+ Vector3.new(0, 1, 0)
end

1 comment

0

Thank you so much!!

I don't think ":children" is an actual method. I pointed this out in my answer to your forum post and you said it worked, so moving on...

The problem is that if you find a spawn that's used you never try and look for another spawn. You just do nothing. This means that if you toggle one spawn as "Used" and the script randomly picks that spawn, it won't spawn the dummy anywhere.

You can fix that by repeating that by repicking the RandomSpawn until it's not used:

repeat
local RandomSpawn=game.Workspace.Spawns:children''[math.random(1,#game.Workspace.Spawns:children'')]
until not RandomSpawn:FindFirstChild("Used").Value
--rest of the code

1 comment

0

:children is a method. It's equivalent to GetChildren, except that it's deprecated.

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