Im using a insanely complicated stock weapon system where editing the way it works or finding hit detection in the weapon itself is likely not an option. Instead when an explosive device goes off it leaves a scorch mark that is parented to the object it most directly effected. My solution is, if an Mesh in the “Breakables” Folder has a new descendant “Explosion” then fire the server.
2 issues arise from doing this.
Descendant added gets fired twice because a descendant was added to the folder via Folder.Child AND a descendant was added to the Child so because of this i need to use a bool val to check if its broken.
I have to use a while loop because of that boolean.
local Breakables = game.Workspace.Breakables
local Remote = game.ReplicatedStorage.BreakObject
local Send
local Mesh
Breakables.DescendantAdded:Connect(function(Desendant)
if Desendant.Name == "Explosion" then
Desendant.Parent.Broken.Value = true
end
end)
while wait() do
for i, v in pairs(Breakables:GetChildren()) do
if v:IsA("MeshPart") or v:IsA("UnionOperation") then
if v.Broken.Value == true and v.Anchored == true then
Remote:FireServer(v)
v.Broken.Value = false
end
end
end
end
This looks very inefficient. Can you not do .ChildAdded? That should only fire once if DescendentAdded is fired twice due to a child being inserted into the explosion.
Can’t you just run the script when the descendant is added?
Breakables.DescendantAdded:Connect(function(Desendant)
if Desendant.Name == "Explosion" then
if (Desendant.Parent.Broken.Value == true) and (Desendant.Parent.Anchored == true) then
Remote:FireServer(Desendant)
end
end
end)
If you want one script to run for multiple objects, you could try using task spawn
local folder = -- put the parts you want in a folder
for i,v in folder:GetChildren() do
task.spawn(function() -- basically creates a sepearate thread/script
while true do
print(v.Name)
task.wait(1)
end
end)
end
This generally isn’t a good idea since you would be creating a loop for every item within the Folder, what you should Instead you is have the while loop outside the for loop which would work the exact same way:
coroutine.wrap(function() -- I get I could use task.spawn or defer but nah
while task.wait(1) do
local Array = folder:GetChildren() -- i prefer to do this (Idk why)
for i,v in Array do -- looks nicer, shorter ¯\_(ツ)_/¯
print(v)
end
end
end)() -- this extra parentheses have the coroutine fire
This would basically be doing the exact same thing, if you wanted to, you can add in another coroutine or a task to prevent yielding.
I understand this, howver the op asked how to run a single script for multiple objects. I was just giving an example of how using task.spawn, you could create a new thread for each object while still only using 1 script
Hey everyone, the solution i was looking for turned out to be this
local Breakables = game.Workspace.Breakables
local Table = Breakables:GetChildren()
local Remote = game.ReplicatedStorage.BreakObject
local Send
Breakables.DescendantAdded:Connect(function(Desendant)
if Desendant.Name == "Explosion" then
Desendant.Parent.Broken.Value = true
end
end)
for _,Mesh in pairs(Table) do
Mesh.ChildAdded:Connect(function(Child)
if Child.Name == "Explosion" then
if Mesh.Broken.Value == true and Mesh.Anchored == true then
Remote:FireServer(Mesh)
print("Fired")
Mesh.Broken.Value = false
end
end
end)
end