Get all children without looping through all of them?

How can I get all of the children without it looping though all of them?

Example:
gif

( I want it to paint the bricks instantly.

1 Like

why don’t you want to loop through the children?

for _, Child in ipairs(Parent:GetChildren()) do
    Child.Color = Color3.new()
end

this would make the color black

I think it’s because the parts don’t instantly all paint at once, since its a loop.

I want it to color the bricks in the model instantly without it doing each one.

I guess you could do it with a union, but I would rather use a loop
it shouldn’t take long to color each part

1 Like

I don’t wanna use a union though. Work at a Pizza Place has a paint system and it paints all at once(with no union). Also, if I used the loop I would have to add unnecessary code to block the player from breaking it. ( By unequipping the tool etc

Hey! So I don’t think a specific function exists for this, you will have to loop through the parts unless someone knows an alternative. One thing I did go ahead and do was try and diagnose your lag with looping, and I’m not able to replicate it.

I put 1000 blocks into workspace, and then I called :GetChildren() on workspace giving me a list with all those parts. I then looped through this list, checked if the child was a PVInstance (part, meshpart, etc.), checked if it’s name was “Part”, and if it was, turned it to black. My point being, there’s no lag associated with looping through and coloring some parts.

Unless I’m mistaken, the “lag” is either your machine having trouble (I doubt it), a yield in your loop, or other scripts lagging your game.

Messy code but if you want to test this out in a fresh baseplate, put this in a script and then run;

local lastPos = Vector3.new(0, 0, 0)

local function genPart()
	local part = Instance.new("Part")
	part.Size = Vector3.new(4, 4, 4)
	part.Anchored = true
	part.Parent = workspace
	return(part)
end

local function genParts()
	
	for i = 1, 10 do
		
		for x = 1, 10 do
			local part = genPart()
			part.Position = lastPos + Vector3.new(4, 0, 0)
			lastPos = part.Position
		end
		
		lastPos = lastPos + Vector3.new(-40, 0, 4)
		
	end
	
	
	
	
end

for i = 1, 10 do
	genParts()
	lastPos = Vector3.new(0, i*4, 0)
end


local function paintParts()
	local childrenList = workspace:GetChildren()
	
	for i, v in pairs(childrenList) do
		if v:IsA("PVInstance") then
			if v.Name == "Part" then
				v.Color = Color3.new()
			end
		end
	end
	
end

wait(5)

paintParts()

ninja editl; this only does 100 blocks at a time but you can experiment with more parts if you want

People are saying I need to gather the parts into an array and send them all in a single invoke. How exactly should I do this?

local function isaModel()
	if Mouse and Mouse.Target and ColorSelection then
		if Mouse.Target.Parent:IsA("Model") and Mouse.Target.Parent:FindFirstChild("Paintable") then
			if Mouse.Target:FindFirstAncestorWhichIsA("ObjectValue").Value == Player then
				for i,v in pairs(Mouse.Target.Parent:GetChildren()) do
					if v:IsA("Part") or v:IsA("WedgePart") then
						local Data = {Part = v, Color = ColorSelection}
						ServerControls:InvokeServer("PaintPart", Data)
						PaintSound:Play()
						PaintSound.PlaybackSpeed = 0.9 + (math.random() * .1)
					end
				end
			end
		end	
	end
end

The “lag” is being caused because you’re sending a bunch of messages from the client to the server separately, which causes that stuttering paint effect.

So basically, if you want everything to happen seamlessly, you’ll simply want the client to do the mouse and model checks, and then tell the server right away “This is the model then needs to be repainted”. The server will receive the message, and you should execute the loop part of the code on the server. Because you’re only sending 1 message over the server instead of many, it will appear to execute all at once

I’ve never had this happen before so I am very confused haha… Mind if you give a example?

loops iterate instantly, in fact my computer can loop 1 billion times in 3 seconds.

2 Likes

So your code outline will be like this;


--This is a local script
local function isaModel()

--check if there is a valid mouse and mousetarget
--check if the player has a selected color
--check if its paintable
--check if the player clicked a valid model

--> fireserver(model, color) to paint this model

end



--This is the server script that fires when invoked
local function onClientRequest(player, model, color) 

for i, v in pairs(model:GetChildren()) do
     if v:IsA("PVInstance") then -- this is just a fancy way of checking if the child is a part/mesh/etc
          
               --put your paintpart logic here

     end
end

I know this is a little weird to try and work with. You’ve basically done all the work already though. You just want to move your loop onto the server, and not the client. Right now when you click a valid model, the client is checking each part and everytime it finds a part to paint, it sends a message to the server that says “Hey, paint this part!”. A lot of messages is slow and has noticable delay though.

So instead what you want is for the client to find a valid model, and then tell the server only once “Hey, I want to paint this model”, and then the server will now loop through the model (instead of the client) and paint each part. Instead of sending 1 message per each part in the model, you’re only sending 1 message per model and letting the server paint each part from there.

Here’s a really rough mockup based on your current code;

--client code below
local function isaModel()
	--check if mouse and target exists
	if Mouse and Mouse.Target and ColorSelection then
		
		--check if the model is paintable
		if Mouse.Target.Parent:IsA("Model") and Mouse.Target.Parent:FindFirstChild("Paintable") then
			
			--create a variable for the model to paint
			local model = Mouse.Target.Parent
			local color = ColorSelection
			
			--fire the server to do the job
			ServerControls:InvokeServer(model, color)
		
		end	
	end
end





--server code below

local function onPaintRequest(player, model, color) -- one thing to note is that the player who sent the request is always the first variable
	
	--you need to check everything for validity here
	if model and model:IsA("Model") then
		
		--get list of model children
		local children = model:GetChildren()
		
		--loop through all children of model
		for i, v in pairs(children) do
			
			--check if they are a part, meshpart, etc.
			if v:IsA("PVInstance") then
				
				v.Color = color -- the color value was sent from the client				
			end
		end	
	end
end

ServerControls.OnServerInvoke = onPaintRequest

I transferred it over and now it isn’t painting anything?

Didn’t work. charr30000000000000

1 Like

A for loop should run instantly if you don’t use wait() in your loop.

1 Like

Wish that was the case for me.

Got it working! thanks to everyone who helped <3