Gun not always detecting character in range of ray

Hello. I am working on a commission, but the player tells me it doesn’t always detect the rays when shooting at the player. Here is my code:

wait(1)
local tool = script.Parent;
local isShooting = false;
local userInputService = game:GetService("UserInputService");
local mouse = game.Players.LocalPlayer:GetMouse();
local reloadRemote = script.Parent.Reload;
local safeRemote = script.Parent.Safe;
local damageRemoteEvent = script.Parent.Damage;
local crouchRemoteEvent = script.Parent.Crouch;
local info = {
	Rate = script.Parent.Rate.Value;
	Range = script.Parent.Range.Value;
	Magezine = script.Parent.Ammo.Value;
	Sprint = script.Parent.Sprint.Value;
	Damage = script.Parent.DamageV.Value;
	Spread = script.Parent.Spread.Value;
	TeamKill = script.Parent.TeamKill.Value;
}

function activated()
	isShooting = true;
end;

function de_Activated()
	isShooting = false;
end;

function on_Unequip()
	isShooting = false
end;

function input_Began(input, gpe)
	if gpe then return end;
	if not script.Parent.Parent:FindFirstChild("Humanoid") then return end;

	if input.KeyCode == Enum.KeyCode.F then
		safeRemote:FireServer()
	end

	if input.KeyCode == Enum.KeyCode.R then
		if not script.Parent.Configuration.IsReloading.Value then
			reloadRemote:FireServer()
		end
	end
	
	if input.KeyCode == Enum.KeyCode.C then
		crouchRemoteEvent:FireServer()
	end
end

userInputService.InputBegan:Connect(input_Began)
tool.Activated:Connect(activated)
tool.Deactivated:Connect(de_Activated)
tool.Unequipped:Connect(on_Unequip)

while wait(info.Rate) do
	if isShooting and not script.Parent.Configuration.IsOnSafe.Value and not script.Parent.Configuration.IsReloading.Value and script.Parent.Ammo.Value ~= 0 then
		local startPosition = script.Parent.Handle.Position;
		local rayCastParams = RaycastParams.new();
		local bulletClone = script.Bullet:Clone();
		bulletClone.Parent = workspace
		bulletClone.CFrame = CFrame.new(script.Parent.ShootPart.Position)
		local bodyVelocity = Instance.new("BodyVelocity");
		local rayUnit = (mouse.Hit.p + Vector3.new(0, 0.07, 0) + Vector3.new(math.random(0, info.Spread), math.random(0, info.Spread), math.random(0, info.Spread)) - bulletClone.Position).Unit * 250
		bodyVelocity.Velocity = rayUnit
		bulletClone.Transparency = 0
		wait(.02)
		bulletClone.Anchored = false
		bodyVelocity.Parent = bulletClone
		rayCastParams.FilterDescendantsInstances = {script.Parent.Parent, script.Parent}
		rayCastParams.FilterType = Enum.RaycastFilterType.Blacklist
		rayCastParams.IgnoreWater = true
		local result = workspace:Raycast(script.Parent.Handle.Position, (mouse.Hit.p + Vector3.new(0, 0.07, 0) + Vector3.new(math.random(0, info.Spread), math.random(0, info.Spread), math.random(0, info.Spread)) - bulletClone.Position).Unit * info.Range, rayCastParams);
		if result ~= nil and result.Instance and result.Instance.Parent:FindFirstChildOfClass("Humanoid") then
			if info.TeamKill then
				damageRemoteEvent:FireServer(result.Instance.Parent:FindFirstChildOfClass("Humanoid"))
			else
				local player = game.Players:GetPlayerFromCharacter(result.Instance.Parent);
				if player then
					if player.Team == game.Players.LocalPlayer.Team then
						print("Player is in the player's team and TK is off.")
					else
						damageRemoteEvent:FireServer(result.Instance.Parent:FindFirstChildOfClass("Humanoid"))
					end
				else
					damageRemoteEvent:FireServer(result.Instance.Parent:FindFirstChildOfClass("Humanoid"))
				end
			end
		end
	else
	end
end

Lines that handle this:

while wait(info.Rate) do
	if isShooting and not script.Parent.Configuration.IsOnSafe.Value and not script.Parent.Configuration.IsReloading.Value and script.Parent.Ammo.Value ~= 0 then
		local startPosition = script.Parent.Handle.Position;
		local rayCastParams = RaycastParams.new();
		local bulletClone = script.Bullet:Clone();
		bulletClone.Parent = workspace
		bulletClone.CFrame = CFrame.new(script.Parent.ShootPart.Position)
		local bodyVelocity = Instance.new("BodyVelocity");
		local rayUnit = (mouse.Hit.p + Vector3.new(0, 0.07, 0) + Vector3.new(math.random(0, info.Spread), math.random(0, info.Spread), math.random(0, info.Spread)) - bulletClone.Position).Unit * 250
		bodyVelocity.Velocity = rayUnit
		bulletClone.Transparency = 0
		wait(.02)
		bulletClone.Anchored = false
		bodyVelocity.Parent = bulletClone
		rayCastParams.FilterDescendantsInstances = {script.Parent.Parent, script.Parent}
		rayCastParams.FilterType = Enum.RaycastFilterType.Blacklist
		rayCastParams.IgnoreWater = true
		local result = workspace:Raycast(script.Parent.Handle.Position, (mouse.Hit.p + Vector3.new(0, 0.07, 0) + Vector3.new(math.random(0, info.Spread), math.random(0, info.Spread), math.random(0, info.Spread)) - bulletClone.Position).Unit * info.Range, rayCastParams);
		if result ~= nil and result.Instance and result.Instance.Parent:FindFirstChildOfClass("Humanoid") then
			if info.TeamKill then
				damageRemoteEvent:FireServer(result.Instance.Parent:FindFirstChildOfClass("Humanoid"))
			else
				local player = game.Players:GetPlayerFromCharacter(result.Instance.Parent);
				if player then
					if player.Team == game.Players.LocalPlayer.Team then
						print("Player is in the player's team and TK is off.")
					else
						damageRemoteEvent:FireServer(result.Instance.Parent:FindFirstChildOfClass("Humanoid"))
					end
				else
					damageRemoteEvent:FireServer(result.Instance.Parent:FindFirstChildOfClass("Humanoid"))
				end
			end
		end
	else
	end
end

2 Likes

I think the problem might be with having the wait between calculating the path for the bullet and calculating the ray, rn, you have this

time to shoot
path to bullet setup to mouse
wait(0.02) – this will actually wait about 0.029, the minimum
raycast to mouse to damage – because of the delay, it won’t be where the bullet points towards if the mouse has moved

I’m not sure what else could cause bullets to “miss” according to the client, I don’t think the lag from firing the remote to deal damage to replicating is the issue

1 Like

I tested that, but it didn’t work. I set the target filter whenever the tool is activated to all the characters in the game, and it looks to make it work better.