This is my current script inside PlayerScripts (its a local script):
for i,v in workspace:GetDescendants() do
if v:IsA("BasePart") then
if v.Name == "KILLBRICK" then
task.spawn(function()
v.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
hit.Parent.Humanoid:TakeDamage(math.huge)
end
end)
end)
end
end
end
I want this script only to run after every part has been loaded into the client
i have tried searching this everywhere, but can’t find it, I cant use :Preload in content provider service because the parts I want to wait for are randomly placed in folders and will change while I develop the game, also StreamingEnabled is set to false (i know this is a bad practice, but my game has a really low amount of parts and it’s better to have everything loaded for better teleports)
(if you are asking why the kill script runs on the client, that’s because there’s moving kill bricks and they can’t properly detect touch on the right moments when serverside making the obby way harder)
does game:IsLoaded() trigger true when every single part is loaded?
also the if not v then repeat task.wait() until v line would it not work since the part hasn’t loaded in the workspace:GetDescendants() wouldn’t catch the part since it hasn’t loaded it
I would try using the ContentProvider service to wait for every instance to load.
It has a RequestQueueSize property that holds a queue for instance loading.
-- Above your code,
local ContentProvider = game:GetService("ContentProvider")
repeat
task.wait()
until ContentProvider.RequestQueueSize == 0
Here is the documentation if you want to know more about what it does.
Instead of trying to wait for every part to load in workspace you could make use of .DescendantAdded
Example:
local function partAdded(v)
if v:IsA("BasePart") then
if v.Name == "KILLBRICK" then
task.spawn(function()
v.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
hit.Parent.Humanoid:TakeDamage(math.huge)
end
end)
end)
end
end
end
workspace.DescendantAdded:Connect(partAdded)
for _, v in workspace:GetDescendants() do partAdded(v) end
If a part loads in workspace after the script is executed it will attempt to bind it.
That function works well, but it could be a bit shorter and easier to read, tbh
If you only compare one or two values, there’s no need for all that indentation with those embedded if statements – you can just do both checks on one line and return early if requirements aren’t met.
Also, I don’t think there’s a need for the task.spawn/coroutine in this particular solution. Just having it wrapped in the .Touched Connection should do just fine.
I took your code block and tweaked it a bit with some more concise checks and simpler formatting to demonstrate.
local function onKillBrickTouched(hit)
local foundHumanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
-- foundHumanoid can be truthy/falsy:
-- (foundHumanoid == true and [humanoid]) if a humanoid is found
-- or (foundHumanoid == false and nil) if it doesn't exist
if not foundHumanoid then return end -- if there's no humanoid, do nothing
foundHumanoid:TakeDamage(math.huge)
end
local function partAdded(v)
if not v:IsA("BasePart") or v.Name ~= "KILLBRICK" then return end
-- if it's not a part (or if it is and the part's name isn't "KILLBRICK"),
-- then the function quits and allows for the next part to be checked.
v.Touched:Connect(onKillBrickTouched)
-- also rolled up the .Touched Connection so it can be run anywhere by reference.
-- Can save a decent amount of performance when connecting to lots of events
end
Edits: Added comments to the script and rolled up the .Touched event