Ignore certain parts in Raycasting?

Sorry if this has been asked before! I read few threads regarding this topic but seems that they aren’t similar to my case.

Currently I’m working on a weapon, and I’m trying to ignore invisible, CanCollide and player’s accessories parts and let the ray cast go through it.

local IgnoreParts = {}
workspace.DescendantAdded:Connect(function(v)
if v:IsA("BasePart") then
	if v.CanCollide == false then
		table.insert(IgnoreParts, v)
	end
	
	if v.Transparency == 1 then
		table.insert(IgnoreParts,v)
	end
	
	if v.Name == "Handle" then
		table.insert(IgnoreParts, v)
	end
end
end)

And I use FindPartOnRayWithIgnoreList to cast the ray, and using CollectionService to grant these part a Tag named Ignore1

							for i = 1,#IgnoreParts do
								cs:AddTag(IgnoreParts[i],"Ignore1")
							end
							
							local ignored = cs:GetTagged("Ignore1")
							local hit,pos,norm = workspace:FindPartOnRayWithIgnoreList(ray,ignored)

I tested it out and it returns to a weird behavior, whenever my mouse is pointing at the Can Collide part, the ray will go straight up:

This also make player’s impossible to hit when mouse is pointing at their accessories, the ray will just go straight up:

Is there any possible way to make the ray ignore the part and go straight through it?

12 Likes

Very simple, remember to use Mouse.TargetFilter to avoid weird going astray when aiming at invisible or non-cancollide parts. Unfortunately, you’ll have to put all the parts under a folder and set the Mouse.TagetFilter on the folder.

Maybe use ChildAdded on Workspace and update the ignore list would fix the issue.

workspace.ChildAdded:Connect(function(child)
    if game:GetService("Players"):GetPlayerFromCharacter(child) then
        for _, child in next, child:GetChildren() do
            if child:IsA("Accessory") then
                table.insert(IgnoreParts, child)
            end
        end
    end
end)

Also using the folder in workspace, you can just throw the folder into IgnoreParts, because the Workspace:FindPartOnRayWithIgnoreList ignores all descendants for each instance.

9 Likes

From a general efficiency point of view, CollectionService seems to be a cleaner way of handling this problem. Parenting ignored parts to a folder and then iterating through the folder to generate a table seems redundant when you have the option of just doing:

local Ignored = CS:GetTagged("Ignored")

@Headstackk as @Operatik mentioned, with your raycasting method all descendants of the instance(s) passed in the Ignored table are ignored. This issue may lay in improper tagging of instances, or not tagging your own Character to be ignored too.

6 Likes

The problem might be as well that you forgot to ignore the instances already present before the DescendantAdded was created.

local IgnoreParts = {}
local ignorefunc = function(v)
if v:IsA("BasePart") then
	if v.CanCollide == false then
		table.insert(IgnoreParts, v)
	end
	
	if v.Transparency == 1 then
		table.insert(IgnoreParts,v)
	end
	
	if v.Name == "Handle" then
		table.insert(IgnoreParts, v)
	end
end
end
workspace.DescendantAdded:Connect(ignorefunc)
for i,v in pairs(workspace:GetDescendants()) do ignorefunc(v) end

And as H_mzah said, the character should also be added.

3 Likes

You mean I have to create a "Physical’ Folder in Workspace and put all the ignoring parts in it? I think Mouse.TargeFilter should solve my problem, but how do I ignore all the parts with it?

							for i = 1, #IgnoreParts do
								cs:AddTag(IgnoreParts[i],"Ignore1")
								mouse.TargetFilter = IgnoreParts[i]
							end

The behavior remains the same.

Edit: I made a can collide part and made the MouseTarget to it, something like this: mouse.TargetFilter = workspace.cancolide
It works as what I expected, but again how do I utilize it and use it in multiple parts? Using a table like I did above?

1 Like

Put anything and everything you want the mouse to not detect into a folder in workspace. Then set the TargetFilter to that folder.

1 Like

Is it necessary? Any other possible ways like using table? I feel like it won’t be efficient if I keep parenting and unparenting instances to folder frequently.

1 Like

You can’t set TargetFilter to a table. TargetFilter takes a value type of Instance, as you can see here, so it can only be set to an object that you can create with Instance.new().

Setting the TargetFilter to a table returns the following error:
bad argument #3 (Object expected, got table)

1 Like

Umm is this only broken for me?

1 Like

Works for me

2 Likes

How do I make Mouse.TargetFilter to ignore multiple parts but not using Folders/Models? I can not parent a player’s accessories to a certain Folder or Model.

Edit: I think the problem is on FindPartOnRayWithIgnoreList. I used Roblox Developer Hub’s How to make a laser gun tutorial, and put the replacing their workspace:FindPartOnRay with FindPartOnRayWithIgnoreList. I put a table that included a part and player’s character as arguments, aka parts to ignore, here’s the outcome behavior:

In the start of the gif, my mouse pointed the place where I expect the ray to be casted at. But when I try clicking that position through the transparent part, the ray casted way up, which is what happening in my game.
FYI, this only happens when the starting point is close to the ignoring part, but not colliding or touching it.

2 Likes

Speaking of Mouse.TargetFilter, it lacks the feature of using a table(or list) of objects rather than using one instance and read all its descendants. That’s why the only temporary band-aid I can think of is using folders and setting Mouse.TargetFilter to it.

A feature request was made as far back since 2015 regarding about using a list for TargetFilter.

1 Like

Instead of relying on Mouse.TargetFilter and using Mouse.Hit to get the mouse’s position, I instead do another raycast from the camera in the direction of the mouse, with the same ignore list as the raycast I was originally trying to perform.

Here’s the module I wrote and that I use for it. Usage instructions are commented at the top of the module, aside from one I forgot to add: use .HitPosition to get the filtered Mouse.Hit.
MouseFilter.rbxm (1.6 KB)

5 Likes

I was reminded that this method was used and shown in one of the older DevForum posts. If I reckon correctly, it casts the ray from the camera using the same ignore list as the original intended raycast. Next, another ray is cast from the gun’s barrel through the hit position of the projected ray.

I have lost track of which post it was. They were probably discussing about an invisible barrier in the game and the rays were astray and unintended while trying to fire through it.

2 Likes

It looks like you forgot to add the laser to the table.

You can make a folder where you can place anything that bullets will ignore

local IgnoreTo = game.Workspace.Bullets_Ignore:GetChildren();
table.insert(ignore, plr.Character)

Edit:

If you wanna make bullets ignore hats just write this:

	for _,players in pairs(game.Players:GetPlayers()) do
		for i, hats in pairs(players.Character:GetChildren()) do
			if hats:IsA("Accessory") then
				hats.Handle.Size = Vector3.new(0,0,0)
			end
		end
	end
1 Like

So how am I going to utilize the ignore table? Mouse.TargetFilter doesn’t support Table yet, they only read the descendants of a Model/Folder.

Please let it supports table… It has been a request since 2015.

2 Likes

Oh, you’re using Mouse.TargetFilter?
That worked for me. (without Mouse.TargetFilter)

1 Like

You can not resize a part to 0,0,0. It will change to 0.05,0.05,0.05 if you attempt to make it 0,0,0
Plus, this also happen no matter what the size of a part is, if you walk closely enough but not colliding your ShootingPart, this also happens, shown in here:

1 Like

I know, but still works good. :face_with_monocle:

1 Like