How to filter out a player's accessories if being shot (raycasting)

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

I am trying to make a fully function raycast gun that filters out accessories so a headshot can still be registered.

  1. What is the issue? Include screenshots / videos if possible!
    The ray counts accessories as “other” and only gives the player the least amount of damage. In real life glasses or a banana accessory wouldn’t save you from a ray.

  2. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I’ve tried ignore part (or the ray cast whitelist) but I’m not sure how to detect another player’s accessory and add it to the whitelist. I’ve only been able to detect the local player’s accessories

here’s my code

local tool = script.Parent
local shoot_part = tool.Shoot
local remote = tool.OnShoot
local bulletamt = script.Parent.Bulletval
--local raycastParams = RaycastParams.new()


local getbv = script.Parent.Bulletval
bulletamt.Value = 12
local remoteI = tool.Onreload

local Workspace = game:GetService("Workspace")

getbv.Changed:Connect(function(Change)
	print("Change:", Change)
	
end)

remote.OnServerEvent:Connect(function(player, position)
	if bulletamt.Value >= 1 then
		
		

-----------------------------------------------------------------------------------------------------------------
		--local descendants = player.Character:GetDescendants()

		
		--for index, descendant in pairs(descendants) do
		--	print("do")
		--	if descendant:IsA("Accessory") then
		--		print("Its acessory")
		--		print(descendant.Name)

		--	end
		--end

		--raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
		--raycastParams.FilterDescendantsInstances = {player.Character:IsA("Accessory")}
		--raycastParams.IgnoreWater = true

		--print(raycastParams.FilterDescendantsInstances)
		--print(raycastParams.IgnoreWater)
		--print(raycastParams.FilterType)
-----------------------------------------------------------------------------------------------------------------
		local origin = shoot_part.Position
		local direction = (position - origin).Unit
		local result = Workspace:Raycast(shoot_part.Position, direction*300, raycastParams)

		local intersection = result and result.Position or origin + direction*300
		local distance = (origin - intersection).Magnitude

		local bullet_clone = game.ServerStorage.Bullet:Clone()
		bullet_clone.Size = Vector3.new(0.1, 0.1, distance)
		bullet_clone.CFrame = CFrame.new(origin, intersection)*CFrame.new(0, 0, -distance/2)
		bullet_clone.Parent = Workspace
		bullet_clone.Transparency = 0.5
		script.Parent.GunShot:Play()
		if result  then
			print(result)
			local part = result.Instance
			print(part)
			local humanoid = part.Parent:FindFirstChild("Humanoid") or part.Parent.Parent:FindFirstChild("Humanoid")
			if humanoid then
				if part.Name == "LeftFoot" or part.Name == "RightFoot" or part.Name == "LeftHand" or part.Name == "RightHand" then
					humanoid:TakeDamage(1)
					print("1")
				elseif part.Name == "Head" then
					humanoid:TakeDamage(50)
					print("50")
				elseif part.Name == "UpperTorso" or part.Name == "LowerTorso" or part.Name == "HumanoidRootPart" then
					humanoid:TakeDamage(20)
					print("20")
				elseif part.Name == "LeftLowerArm" or part.Name == "RightLowerArm" or part.Name == "LeftUpperArm" or part.Name == "RightUpperArm" or part.Name == "Left Arm" or part.Name == "Right Arm" or part.Name == "Right Leg" or part.Name == "Left Leg" then
					humanoid:TakeDamage(10)
				else
					humanoid:TakeDamage(5)
					print("10")


				end

			end
			
			
		end
		
		print(script.Parent.Bulletval.Value)
		script.Parent.Bulletval.Value = script.Parent.Bulletval.Value - 1
		print(script.Parent.Bulletval.Value)
		--bullet stuff
		local b = " bullets"
		local amt = bulletamt.Value
		script.Parent.GunInterface.Frame.TextLabel.Text = amt .. b
		
		wait(0.25)
		bullet_clone:Destroy()
	
	elseif getbv.Value == 0 then
		print("No more bullets")
		script.Parent.Click:Play()
	end
		
end)
	


remoteI.OnServerEvent:Connect(function(player, client)
	if script.Parent.Bulletval.Value == 0 then
		script.Parent.Bulletval.Value = 12
		print("Reloaded")
		local b = "bullets"
		print(player)
		script.Parent.Gunreload:Play()
		player.PlayerGui.GunInterface.Frame.TextLabel.Text = script.Parent.Bulletval.Value .. b
		
	end

end)

That deals with all of the damage so that’s where I need the raycast to filter accessories. As you can see I have some code of what I’ve tried but it doesn’t work as expected so I’m looking for help.

1 Like

One way to accomplish this would be to construct a table of the “valid” parts in the character model. In your case this may be the “Head” and “Torso” parts. Another (probably better) solution would be to weld an invisible part to the character’s model. You could weld one for the “Head” and one for the “Body”. You can then either parent these hitboxes to the Character’s model and have to repeat the same process of constructing a table of valid parts, OR create a separate Model in the Workspace (maybe named “HitboxCollection”) which you can then use in your whitelisted raycast. If you opt for the invisible parts parented to a central model, you will need to add a way to detect which parts are associated to what Player (and therefore their character). You can do this by simply adding an ObjectValue with its Value property set to the Player it belongs to.

2 Likes

Dunno why you commented out RaycastParams constructor, that’s exactly right!
RaycastParams adds extra functionality and customisation to your raycast, you’ll need to modify FilterType and FilterDescendantsInstances.

2 Likes

I would use it but then I’d have to get the target and in this case, the target is being hit by the ray so I can’t get the target before the ray is fired

So filter every single player in the game’s accessories then?

Thanks for the idea! I have started on that but I keep getting a wait for child error. I’ll do so troubleshooting though. Thanks again!

1 Like