Any way to table.insert into RaycastParams.FilterDescendantsInstances

I’m currently making a gun and to make it shoot I cast a ray to mouse.Hit.p and search for a humanoid of the parent of the Instance of the ray:

local Bullet = workspace:Raycast(Origin, (HitPos - Origin).unit * 1000,BulletParams)

if Bullet then
	if Bullet.Instance.Name ~= "Head" then
		local hum = Bullet.Instance.Parent:FindFirstChild("Humanoid")
	end
end

Only problem with this is that if the ray hits an accessory that the player is wearing, it will not detect the humanoid and therefore do no damage. My work around for this is if the Ray hits an accessory it will add that accessory to it’s ignore list and recast the ray to the same position. To my disappointment I figured out that you can’t table.insert anything into raycastParams.FilterDescendantsInstances from this post.

Is there any work from this? I could just use Ray.new() instead of WorldRoot:Raycast() but I don’t want to use deprecated methods that I’m not used to.

You’ll have to grab the current table, insert, then set it back.

local list = BulletParams.FilterDescendantsInstances
table.insert(list, accessory)
BulletParams.FilterDescendantsInstances = list
4 Likes

You could use the power of collision groups and set all collideable parts to a specific collision group.

Then, when casting the raycast, you can specify which collision group to check against.

RaycastParams.CollisionGroup = RaycastIgnoreCollisionGroup

It’s basically whitelisting parts to that collision group only.

This would require you to set the collision group of all parts you want ignored into a separate group. It’s better then having to recast multiple rays whenever an accessory is hit. You can set the accessory parts to a collision group when the character spawns.

1 Like

This worked but it’s acting kind of strange. The accessory does get added to the ignore list but the ray doesn’t ignore it. You can see in this video, the table is the ignore list and what is being printed above it is what the ray is hitting.


“Handle” is a child of the accessory so if I’m not mistaken it should get ignored.

The easiest solution is my eyes is the collision group.

You can simply just add the accessory parts into a specified collision group when the character respawns. Instead of having to loop through all characters.

Player.CharacterAdded:Connect(function(character)
    -- Add all accessory parts into a collision group that ingores default collisions.
end)

Sorry, I should’ve done a bit more testing before marking it as the solution. It seemed to work the first time and then randomly stopped working. In the script where I cast the ray I have these loops to put all accessories into the “Ignored” collision group.

local PhysicsService = game:GetService("PhysicsService")

PhysicsService:CreateCollisionGroup("Ignored")

for i,v in pairs(workspace:GetChildren()) do
	if v:IsA("Model") then
		for i,ModelPart in pairs(v:GetChildren()) do
			if ModelPart.Name == "Humanoid" then
				for i, Accessory in pairs do
					if Accessory:IsA("Accessory") then
						for i,AccessoryDescendants in pairs(Accessory:GetDescendants()) do
							PhysicsService:SetPartCollisionGroup(AccessoryDescendants, "IgnoredParts")
						end
					end
				end
			end
		end
	end
end

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		for i,Accessory in pairs(char:GetChildren()) do
			if Accessory:IsA("Accessory") then
				for i,AccessoryDescendants in pairs(Accessory:GetDescendants()) do
					PhysicsService:SetPartCollisionGroup(AccessoryDescendants, "Ignored")
				end
			end
		end
	end)
end)

BulletParams.CollisionGroup = "Ignored"

It doesn’t seem to ignore the accessories. Is everything here correct? I have very minimal knowledge of CollisionGroups as I haven’t worked with them much so I very well could have something incorrect.

All good, it’s all a learning process in the end.

An issue that can arise is the charatcer not being able to load all accessories on the time of spawn. You could instead hook a ChildAdded event to the character and check if that child is an accessory. If so, add it to the ignore group. This code was tested and works on studio.

Take note that every game has a Default collision group. Which encapsulates regular collisions. You can set the hat collision group to not collide with the Default collision group. (Basically everything else in the game)

local Players = game:GetService("Players");
local PhysicsService = game:GetService("PhysicsService");

local HatsCollisionGroupName = "IgnoreHats"

PhysicsService:CreateCollisionGroup(HatsCollisionGroupName); -- Creates the collision group
PhysicsService:CollisionGroupSetCollidable("Default", "IgnoreHats", false); -- Hats cannot collide with the Default group.

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		character.ChildAdded:Connect(function(child) -- Every object added into the character, we check if it's an accessory
			if child:IsA("Accessory") then
				for i,d in pairs(child:GetDescendants()) do -- Loop through the accesories descendants
					if (d:IsA("BasePart")) then
						PhysicsService:SetPartCollisionGroup(d, HatsCollisionGroupName); -- Adds any basepart descendant to the ignore group
					end
				end
			end
		end)
	end)
end)


local rayparams = RaycastParams.new();
rayparams.CollisionGroup = "Default"; -- Only allow collision with parts that have the Default collision group
1 Like

Didn’t set the 2 collision groups to not collide. I now understand another useful service! Thanks for your help :smile:

1 Like

you can also just make any exclusion that has cancollide set to false by disabling canquery, as for parts that can collide you can make a function, add a local table inside the function. You want to loop through the children of workspace, or descendants (if neccessary) and specifcy objects and insert them in the table then outside the loop make the function return the table, and set the RaycastParams.FilterDescendantsInstances to the function.

It would go something like this:

-- Imaginary Beam between 2 parts except with your blacklisting need
local Part1 = workspace:FindFirstChild("ImaginaryPart")
local Part2 = workspace:FindFirstChild("ImaginaryPart2")
local function GenerateBlackList()
	local BlackList = {}
	for x, instance in pairs(workspace:GetDescendants()) do
		if instance:IsA("Accessory") then
			table.insert(BlackList, instance)
		end
	end
	return BlackList
end
local RayOptions = RaycastParams.new()
RayOptions.FilterDescendantsInstances = GenerateBlackList
RayOptions.FilterType = Enum.RaycastFilterType.Blacklist
local RAY_CAST = workspace:Raycast(Part1.Position, (Part2.Position - Part1.Position).Unit * 1000, RayOptions)
print(RAY_CAST)
-- if you step in between the two parts during the ray but only your accessory is in the way it will go right through it since it is of the accessory class
-- the ray will succesfully hit the part2