How can I get all of the children without it looping though all of them?
Example:
( I want it to paint the bricks instantly.
How can I get all of the children without it looping though all of them?
Example:
( I want it to paint the bricks instantly.
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
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.
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
A for loop should run instantly if you don’t use wait()
in your loop.
Wish that was the case for me.
Got it working! thanks to everyone who helped <3