Multiple Running Iterator Functions?

So I created an iterator and a region3. Every time someone is inside the region, it prints their name multiple times. I tested with 2 people, but every time someone else goes in after the first person did, it doesn’t print their name anymore. I don’t know if the solution is very obvious… I tried using coroutines but that just would run a single time. (Even when adding coroutine.yield() )

for i, v in pairs(region_p) do
	if v.Parent:FindFirstChild("Humanoid") and v.Name == "Head" then
		local player = game.Players:GetPlayerFromCharacter(v.Parent)
		print(player.Name)
		--DrRe:FireClient(player, value)
	end
end

Thanks in advance.

3 Likes

You’d have to wrap it in a loop to check for players every x amount of time. You can also check multiple regions at one time with coroutines which allow multiple threads to be ran in a single script at a single time.

while true do
    local regionParts = workspace:FindPartsInRegion3(--[[args]])
    for i,v in pairs(regionParts) do
        -- if statements checking for humanoid and head
    end
    wait(0.1) -- sets how long to wait before checks.
end

If you want to check multiple regions at one time, you would have to use coroutines

local regions = {RegionA, RegionB, RegionC}

for i,region in pairs(regions) do
    coroutine.wrap(function() -- best to use wrap as it returns any errors when called
        while true do
            local regionParts = workspace:FindPartsInRegion3(region) -- your region as declared in the for pairs loop above
            for i,v in pairs(regionparts) do
                -- add those if statements from above
            end
         wait(0.1) -- wait 0.1 seconds between each loop
         end
    end)() -- it is crucial to have these extra parentheses as it is what calls or "initiates" the coroutine. You could also use the coroutine as a variable and it will work in a similar way.
    --[[local myCoroutine = coroutine.wrap(function()
            print('Cool coroutine function.')
        end) <-- ensure the extra brackets aren't there when using the coroutine as a variable.
        myCoroutine() <-- Call the coroutine similarly to how you would call a function.
    ]]
end

Pardon if I don’t understand, but I didn’t want multiple regions. I only have 1 region with multiple people.

2 Likes

After reading your code snippet, I can confirm that it should print the name of every character that is inside the region when it is ran.

Could you explain more about what you are trying to accomplish?

probably the loop is going through already stored values in variable region_p, try using the actual function workspace:FindPartsInRegion3

example:

for _, something in pairs(workspace:FindPartsInRegion3(your_region)) do

end
1 Like

It still doesn’t function with multiple people, but I get what you’re saying.

1 Like

Ex: A player goes into the region. It repeatedly prints his/her name, until someone else comes into the region. Now instead of printing both names, it only prints the player that went after the first person that went into the region.

I need it so both names get printed, but somehow it prints the player that goes in after.

1 Like

The code provided does seem to be only a part of what you want, and does seem like it should work as expected.

Could you provide more code?

1 Like

Just ignore the stuff that you don’t know or isn’t relevant to this topic…

for i, v in pairs(workspace:GetDescendants()) do
	if v:FindFirstChild("_Water") then
		local value = v:FindFirstChild("_Water")
		local function water_find()
			
			while true do
				wait(0.1)
				local region_v = Region3.new(v.Position - v.Size/2, v.Position + v.Size/2)
				--local region_p = workspace:FindPartsInRegion3WithIgnoreList(region_v, ignorelist)
				for _, v in pairs(workspace:FindPartsInRegion3(region_v)) do
					if v.Parent:FindFirstChild("Humanoid") and v.Name == "Head" then
						local player = game.Players:GetPlayerFromCharacter(v.Parent)
						print(player.Name)
						DrRe:FireClient(player, value)
					end
				end
			end
		end
		local rep = coroutine.create(water_find)
		coroutine.resume(rep)
	end
end
2 Likes

Don’t create a new Region3 inside of the while true do loop. Otherwise the code seems to look alright, it’s just the order in which you are doing things.

for i,v in pairs(workspace:GetDescendants()) do
    local value = v:FindFirstChild('_Water')
        if value then -- just shortens it a tiny bit
        local region_v = Region3.new(v.Position - v.Size/2, v.Position + v.Size/2) -- create the region here, not inside of the while loop.
        local rep = coroutine.wrap(function() -- use wrap, it will output the errors. coroutine.create won't, similar to a pcall IIRC. You can also wrap in a variable like this.
            while true do
	    			wait(0.1)
	    			for _, v in pairs(workspace:FindPartsInRegion3(region_v)) do
	    				if v.Parent:FindFirstChild("Humanoid") and v.Name == "Head" then
	    					local player = game.Players:GetPlayerFromCharacter(v.Parent)
	    					print(player.Name)
	    					DrRe:FireClient(player, value)
	    				end
	    			end
	    		end
            end
        end)
        rep() -- you don't have to resume it. Just call it as you would call a function.
    end
end

Unfortunately, it did the same thing like normal.

Edit: Yes, the output printed the same like last time :confused:

Edit 2: Also, you’re script was a little broken, so I had to re-fix the end.

1 Like

Sorry about that.

I made a little edit, moved where the region3 was created. Check if anything else is printed.

If not, try printing workspace:FindPartsInRegion3(region_v)

I tried your first attempt, which wasn’t the solution.
Also, for the second suggestion you’ve made, it still printed the same thing…

1 Like

I mean try commenting out the loop, then print it outside of that loop. Add it inside of the while true do loop though.

It should print an array/table.

while true do
    wait(0.1)
    print(workspace:FindPartsInRegion3(region_v))
	   --[[for _, v in pairs(workspace:FindPartsInRegion3(region_v)) do
	       	if v.Parent:FindFirstChild("Humanoid") and v.Name == "Head" then
				local player = game.Players:GetPlayerFromCharacter(v.Parent)
				print(player.Name)
				DrRe:FireClient(player, value)
			end]]
	 end
end

Oddly enough, when both of the players collided with the region, the output inserts a table, but none of the player’s name got pasted. Also, since the water (region) is colliding with the baseplate, it prints that out, too. (And, it prints out another object I’ve added in the workspace that isn’t colliding or near the region)

Output:

  [1] = Baseplate,
  [2] = Acid

Edit: I forgot, if the object has _Water in it, it can only be printed (or that’s what I assumed)

1 Like

That’s really strange. Could you provide a model/place file? If you can’t, I will make one myself and test that out.

I changed the previous post. Maybe that can help?

1 Like

I’ll make one using your code. Only thing I could see that would be “wrong” at this point would be the size when declaring the region_v variable.

I’ll re-set the script like how it was originally, and give you the exact copy. (I don’t know how, honestly)

1 Like

I think I may have found the issue. If this fixes it, it was just your constructors for your Region3. I ended up not copying your game but let me know if this helps any or at least prints anything when the user enters the part.

for i, v in pairs(workspace:GetDescendants()) do
    if v:FindFirstChild("_Water") then
        local value = v:FindFirstChild("_Water")

        --// Construct the bounds for the Region3 //--

        local bounds_1 = Vector3.new(
            v.Position.X + (v.Size.X / 2),
            v.Position.Y + (v.Size.Y / 2),
            v.Position.Z + (v.Size.Z / 2)
        )
        local bounds_2 = Vector3.new(
            v.Position.X - (v.Size.X / 2),
            v.Position.Y - (v.Size.Y / 2),
            v.Position.Z - (v.Size.Z / 2)
        )
        
        --// Find the minimum and maximum Vector3 for the Region3 //--
        
        local bounds_min = Vector3.new(
            math.min(bounds_1.X, bounds_2.X),
            math.min(bounds_1.Y, bounds_2.Y),
            math.min(bounds_1.Z, bounds_2.Z)
        )
        
        local bounds_max = Vector3.new(
            math.max(bounds_1.X, bounds_2.X),
            math.max(bounds_1.Y, bounds_2.Y),
            math.max(bounds_1.Z, bounds_2.Z)
        )
        
        local region_v = Region3.new(bounds_min, bounds_max)
        while true do
            print(workspace:FindPartsInRegion3(region_v))
            wait(1)
        end
    end
end