I’m making a weapon system that uses raycasts to find multiple player characters, but it isn’t working as there’s a crash bug in it:
module.findHits = function(chr, length)
if chr.className == "Model" then
local humanoid = chr:FindFirstChild("Humanoid")
if humanoid then
local primary = humanoid.RootPart
rcParams.FilterDescendantsInstances = {chr}
rcParams.FilterType = Enum.RaycastFilterType.Blacklist
local result
local results = {}
while true do
result = game.Workspace:Raycast(primary.position, primary.CFrame.LookVector*length, rcParams)
if result and result.Instance and result.Instance.Parent.ClassName == "Model" then
table.insert(results, result)
table.insert(rcParams.FilterDescendantsInstances, result.Instance.Parent)
print(rcParams.FilterDescendantsInstances)
else
break
end
end
return results
else
error("Not a valid object")
end
else
error("Tried to detect for weapon hit from non-model object")
end
end
The thing is that it’s not adding anything to the rcParams.FilterDescendantsInstances object, making the game crash due to it not breaking the loop. Why doesn’t it add the instance’s parent to the list?
In your loop, you didn’t add a wait() thus crashing your game/client;
while loops tend to crash if there isn’t a wait() inside them.
while true do
result = game.Workspace:Raycast(primary.position, primary.CFrame.LookVector*length, rcParams)
if result and result.Instance and result.Instance.Parent.ClassName == "Model" then
table.insert(results, result)
table.insert(rcParams.FilterDescendantsInstances, result.Instance.Parent)
print(rcParams.FilterDescendantsInstances)
else
break
end
task.wait(1/60) -- Add a wait here, so the loop doesn't cause a crash
end
The problem isn’t recursion. It’s that the raycast doesn’t add the hit part to result; if all the parts
parents are blacklisted, the raycast won’t hit anything; therefore making result and result.Instance==null, triggering the break. My problem is that it won’t add to rcParams.filterDescendantsInstances, making it recur forever.
This is a very frustrating issue I’ve experienced with using these new modifier objects.
You have to manually construct a new table, add all of your instances in that, and then assign that table as the new value of the FilterDescendantsInstances field.
local function cloneFilterInstancesTable(rcParams)
local newTable = {}
for _, instance in ipairs(rcParams.FilterDescendantsInstances) do
table.insert(newTable, instance)
end
return newTable
end
I’ve actually never tried this though, so I’m not sure if the results would be as expected when trying to read the FilterDescendantsInstances table.
To put it simply, you construct a new table value, unpack the currently filtered instances from its table into the constructed one and add additional instances to the constructed table.