RayCast issues at close distances

FINAL EDIT
I have solved this issue already, but I am still open to better ideas as mine was NOT the most practical. Essentially what I did was if the caster was close enough to the target, then a ray would cast from the casters torso into the targets torso so i could get the center of the targets character. Then I would measure the distance from the position of the mouse and the center of the target. If the distance was greater than .8 and the mouse has a target then, its a headshot, anything lower there is a bodyshot.

CLARIFICATION
this is a view model gun, but the player still holds a tool that the ray comes out of

My issue is that everytime you get within 2 or 1 studs of a player, like up in their face the ray glitches and hits the actual tool instead, I think this happens because the tool’s hole is past the players head and the players head is behind the gun so the ray would fire backwards. Things that I have tried are as followed:

  • casting a ray from the shooters head, but this results in the ray hitting my accessories. I tried to make the ray ignore my accessories, but I also have to make the ray ignore the targets accessories, and I am not sure how to make FilterDescendantsInstances ignore two tables.

  • Using the mouse.TargetFilter property but from previous experience using it, I don’t think it would work well here as I’d have to set the filter to what the mouse’s target is, which just won’t work cause the target would already be the target and filtering it after would make no sense.

  • Casting a ray from the casters HumanoidRootPart but that would mean that the ray would travel from the middle of the casters body to the targets head and if the caster were to aim at the head then the ray would most likely hit the targets torso instead

Any help is appreciated!

--client side
tool.fire.OnServerEvent:Connect(function(plyr,char,dest)
	sounds.shoot:Play()
	local dist = math.floor((dest-tool.Hole.Position).Magnitude)
	print(dist)
	if char ~= nil and char ~= plyr.Character then
		local rayOrigin = tool.Hole.Position
		local rayDirection = dest
		local ray = RaycastParams.new()
		if char:FindFirstChild("Humanoid") then
			ray.FilterDescendantsInstances = char.Humanoid:GetAccessories()
		end
		ray.FilterType = Enum.RaycastFilterType.Blacklist
		local rayresult = workspace:Raycast(rayOrigin, (rayDirection-rayOrigin).Unit*450, ray)
		if rayresult then
			if rayresult.Instance ~= nil then
				local hitpart = rayresult.Instance
				print(hitpart)
				if hitpart.Parent:FindFirstChild("Humanoid") and hitpart.Name == "Head" then
					hitpart.Parent.Humanoid:TakeDamage(100)
				elseif hitpart.Parent:FindFirstChild("Humanoid") and hitpart.Name ~= "Head" then
					hitpart.Parent.Humanoid:TakeDamage(45)
				end
			end
		end
	end
end)
--serverside
tool.fire.OnServerEvent:Connect(function(plyr,char,dest)
	sounds.shoot:Play()
	local dist = math.floor((dest-tool.Hole.Position).Magnitude)
	print(dist)
	if char ~= nil and char ~= plyr.Character then
		local rayOrigin = tool.Hole.Position
		local rayDirection = dest
		local ray = RaycastParams.new()
		if char:FindFirstChild("Humanoid") then
			ray.FilterDescendantsInstances = char.Humanoid:GetAccessories()
		end
		ray.FilterType = Enum.RaycastFilterType.Blacklist
		local rayresult = workspace:Raycast(rayOrigin, (rayDirection-rayOrigin).Unit*450, ray)
		if rayresult then
			if rayresult.Instance ~= nil then
				local hitpart = rayresult.Instance
				print(hitpart)
				if hitpart.Parent:FindFirstChild("Humanoid") and hitpart.Name == "Head" then
					hitpart.Parent.Humanoid:TakeDamage(100)
				elseif hitpart.Parent:FindFirstChild("Humanoid") and hitpart.Name ~= "Head" then
					hitpart.Parent.Humanoid:TakeDamage(45)
				end
			end
		end
	end
end)
2 Likes

What if the actual tool is CanCollide on? Then when you walk up it should hit and not fire backwards.

1 Like

This won’t work the player would still be able to shove the tool past the target’s head, also I forgot to mention the gun is a View Model gun, but the ray still comes out of the actual tool that the player holds

1 Like

Try adding to the ignore list.

In both of your scripts, you have only ignored accessories.

if char:FindFirstChild("Humanoid") then
	ray.FilterDescendantsInstances = char.Humanoid:GetAccessories()
end

Instead, make a table that includes everything in the character.

raycastParams.FilterDescendantsInstances = {
     char:GetDescendants();
}

This will ignore accessories, body parts, and the tool equipped.

Just tried this right now and it didn’t work because the tool also contains other things such as scripts sounds and remote event. so I used a for loop to loop through the tool and insert all parts that were parts, but it just didn’t work, I dont know if thats because of filter descendants or cause of the ray.

You can filter the whole character instead of just the accesories.