Blacklist multiple parts for mouse.hit?

Hello everyone, I am making the player face the mouse. My current code works fine, but sometimes, invisible parts like hitboxes interfere with it. So, I am trying to use Mouse.TargetFilter to filter out everything except the terrain.

However, It seems that Mouse.TargetFilter can’t filter out more than one item and it’s descendants. The thing is, I can’t put all parts into a folder, because it would make me have to reorganize everything, and generally be a huge pain. Is there any way to avoid having to reorganize the entire game?

My code is

	local character = Player.Character or Player.CharacterAdded:Wait()
	
	while character:FindFirstChild("Humanoid").Health > 0 do
		game:GetService("RunService").Stepped:Wait()
		local Children = game.Workspace:GetChildren()
		character.UpperTorso.CFrame = CFrame.new(character.UpperTorso.Position, Vector3.new(mouse.Hit.p.X, character.UpperTorso.Position.Y, mouse.Hit.p.Z))
	end

I was thinking that I could loop through all descendants of workspace that are parts and set canquery to false, and then after changing the character’s CFrame, immediately change it back. Although, that seems like a really bad solution

1 Like

You should use a Raycast when the player clicks and do filtering on it as it takes a full table and can use white or blacklist

I don’t know how to do that…
I tried something like that, but couldn’t figure out how to actually make the player face the mouse:

local camera = game.Workspace.CurrentCamera
--mouse.TargetFilter = game.Workspace
function getMouseTargetWithFilter(cursorPosition, filter)
	local ray = camera:ScreenPointToRay(cursorPosition.x, cursorPosition.y, 900)
	
	
	return workspace:FindPartOnRayWithIgnoreList(ray, filter)
end
game.ReplicatedStorage.Play.Event:Connect(function()
	local character = Player.Character or Player.CharacterAdded:Wait()
	
	while character:FindFirstChild("Humanoid").Health > 0 do
		game:GetService("RunService").Stepped:Wait()
		local Children = game.Workspace:GetChildrenOfClass()
		for count = 1, #Children do
			if Children[count].Name == "Terrain" then
				table.remove(Children,Children[count])
				break
			end
		end
		
		character.UpperTorso.CFrame = CFrame.new(character.UpperTorso.Position, Vector3.new(mouse.Hit.p.X, character.UpperTorso.Position.Y, mouse.Hit.p.Z))
	end
end)

try something like this. you will need to finish the raycast itself but this is how you could set it up

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {}  -- don't target objects in this table...
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist 
local MouseHitPos = mouse.Hit.Position
local RayDistance = (Camera.CFrame.Position - MouseHitPos ).Magnitude + 1   -- this gets distance and shoots ray from camera to mouse hit + 1 stud 
local RaycastResult2 = workspace:Raycast(Camera.CFrame.Position, CFrame.new(Camera.CFrame.Position, MouseHitPos).LookVector * RayDistance,raycastParams)   -- cast from camera 1 stud further than mouse click
1 Like

Have you tried using TargetFilter into a folder? If you do that, it should filter all the parts on the folder.

I will try this tomorrow since I am very tired now. Thanks so much!

1 Like

Posting the solution here as well.

1 Like