Hitscan hitreg not working

I got a gun system working but the hitreg is very inconsistent
the accessories are not blocking the bullets because extending the raycast further does not fix the issue
this is the script in ServerScriptService

game.ReplicatedStorage.gunshoot.OnServerEvent:Connect(function(Player, TargetLocation, Handles, gundamage, raynge)
	if Player.Character == nil then -- Make sure their character exists.
		return
	end

	Handles.Sound:Play()

	local Beam = Instance.new("Part", workspace)
	Beam.BrickColor = BrickColor.new("New Yeller")
	Beam.FormFactor = "Custom"
	Beam.Transparency = 0.4
	Beam.Material = "Metal"
	Beam.Anchored = true
	Beam.CanCollide = false


	-- Math.
	local Distance = (Handles.Position - TargetLocation).magnitude
	Beam.Size = Vector3.new(0.1, 0.1, Distance +1.5)
	Beam.CFrame = CFrame.new(Handles.Position, TargetLocation) * CFrame.new(0, 0, -Distance/2)

	game.Debris:AddItem(Beam, 0.1) -- Destroy.

	-- Raycasting [Shoot a ray, get wherever it hit]
	local NewRay = RaycastParams.new()
	local RayDirection = (TargetLocation  - Handles.Position) * raynge -- how far you want the ray to travel before stopping.

	NewRay.FilterDescendantsInstances = {Player.Character}

	local Result = workspace:Raycast(Handles.Position, RayDirection, NewRay)

	if Result then -- IF we got a result back.
		if Result.Instance then
			-- It actually hit something.

			if Result.Instance.Parent:FindFirstChild("Humanoid") then
				Result.Instance.Parent.Humanoid.Health -= gundamage
			
			end
		end
	end
end)

Ray code seems ok,

Im guessing the inconsistency is due to lag since its an on server event.

You can double check this by moving the code to client for testing only.

For a fix if the reason is lag, thats complicated but has been done before you can try searching up on it.

Are you sure the accessories are not blocking it? Because its only checking Instance parent, and every accessory has a part in it called Handle so it will not pass the check when hitting the hat.

To make sure, disable CanQuery for the Handle in the Accessories on the server, then check if it works.

When I made a gun and it didnt detect that was the problem so it might be the same.

Yes what you should do is fire this raycast on the client to get the most accurate results. if you do it on the server you are not getting the exact cframe or orientation of the player because that information is throttled. Then fire the raycast result to the server along with everything else.

I did raycasts on server as I just like it a bit more and I kinda was already too deep into server sided bullets so I just rolled with it, I decreased the delay from server to client information by requesting the clients character cframe through remote function, and it works pretty well.

The thing is you are potentially firing too much server events. I’ve seen others code like this.
—Example
while true do
task.wait(.1)
Remote:FireServer(Root.CFrame)
end

but in reality it should be connected to the firing signal and only be looping while firing.
when that firing is connected.
local Cframeloop=nil

Cframeloop=while Firing do
task.wait(.1)
Remote:FireServer(Root.CFrame)
end
Cframeloop:Connect()

then when it’s done firing you could make firing false or disconnect the Cframeloop
Cframeloop:Disonnect(). This is better practice for performance reasons.

I’m confused, how should I implement this solution?

What are you talking about? When I want the charcters cframe I just use :InvokeClient with a remote function to get it, theirs no need for a loop.

You should fire your CFrame through the local trigger of your gun not fireserver() then,:InvokeClient unless you are running a conditional to get another players local CFrame. But if you were to do that you should still get the CFrame from the server then compare the two and use the average. Because otherwise by the time it gets back to the client your gun would have some sort of delay in it that would make it have worse accuracy depending on ping.
If you were to use the average position you would get the center-point of that movement thus in theory getting a much more accurate position.

im just as confused??
im sorry for all of these replies i just barely know what im doing

Okay I understand so i looked over your code and I believe the main issue you are having is that when you hit an accessory your code does not get the humanoid. So you can copy and paste this over youre inital code you posted.

game.ReplicatedStorage.gunshoot.OnServerEvent:Connect(function(Player, TargetLocation, Handles, gundamage, raynge)
if Player.Character == nil then – Make sure their character exists.
return
end

Handles.Sound:Play()

local Beam = Instance.new("Part", workspace)
Beam.BrickColor = BrickColor.new("New Yeller")
Beam.FormFactor = "Custom"
Beam.Transparency = 0.4
Beam.Material = "Metal"
Beam.Anchored = true
Beam.CanCollide = false


-- Math.
local Distance = (Handles.Position - TargetLocation).magnitude
Beam.Size = Vector3.new(0.1, 0.1, Distance +1.5)
Beam.CFrame = CFrame.new(Handles.Position, TargetLocation) * CFrame.new(0, 0, -Distance/2)

game.Debris:AddItem(Beam, 0.1) -- Destroy.

-- Raycasting [Shoot a ray, get wherever it hit]
local NewRay = RaycastParams.new()
local RayDirection = (TargetLocation  - Handles.Position) * raynge -- how far you want the ray to travel before stopping.

NewRay.FilterDescendantsInstances = {Player.Character}

local Result = workspace:Raycast(Handles.Position, RayDirection, NewRay)

if Result then -- IF we got a result back.
	if Result.Instance then
		-- It actually hit something.
		if Result.Instance.Parent:FindFirstChild("Humanoid") then
			Result.Instance.Parent.Humanoid.Health -= gundamage
		elseif Result.Instance.Parent.Parent:FindFirstChild("Humanoid") then
			Result.Instance.Parent.Parent.Humanoid.Health -= gundamage
		end
	end
end

end)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.