Ray not consistent with detecting a part

I am making a gun and trying to add bullet particles like when it hits somethings particles pop out and for some unknown reason its not consistent like its a chance if they pop.

Video to give you the idea

local Gun = script.Parent
local Config = Gun:WaitForChild("Config")
local Handle = Gun:WaitForChild("Handle")
local Nozzle = Handle:WaitForChild("Nozzle")

local function Tween(O,D,G)
	game:GetService("TweenService"):Create(O,TweenInfo.new(D),G):Play()
end

local function Particles(Color,Material,CF)
	for i = 1,10 do
		local Particle = Instance.new("Part")
		Particle.Color = Color
		Particle.Material = Material
		Particle.CFrame = CF
		Particle.Velocity = Particle.CFrame.LookVector*20
		Particle.CanCollide = false
		Particle.Parent = workspace
		Particle.Size = Vector3.new(0.5,0.5,0.5)
		coroutine.resume(coroutine.create(function()
			wait(0.1)
			Particle.CanCollide = true
			wait(5)
			Tween(Particle,2,{Transparency = 1})
			wait(2)
			Particle:Destroy()
		end))
	end
end

local function visualize(origin,position)
	local distance = (origin - position).Magnitude
	local p = Instance.new("Part")
	p.Parent = workspace
	p.Anchored = true
	p.CanCollide = false
	p.Size = Vector3.new(0.1, 0.1, distance)
	p.CFrame = CFrame.lookAt(position, origin)*CFrame.new(0, 0, -distance/2)
	p.BrickColor = BrickColor.new("Gold")
	p.Material = Enum.Material.Neon
	Tween(p,0.1,{Transparency = 1})
	game:GetService("Debris"):AddItem(p,0.1)
	return p
end

local function Shoot(End,Origin,Part)
	visualize(Origin.Position,End)
	if Part then
		wait(0.1)
		Particles(Part.Color,Part.Material,CFrame.lookAt(End,Origin.Position)*CFrame.Angles(0,math.random(180),0))
	end
end

Gun.Visualize.OnServerEvent:Connect(function(player,Part,Position,Origin)
	Shoot(Position,Origin,Part)
end)

Server

local Player = game.Players.LocalPlayer
local Gun = script.Parent
local Config = Gun:WaitForChild("Config")
local Handle = Gun:WaitForChild("Handle")
local Bullet = script:WaitForChild("Bullet")
local GUI = script:WaitForChild("GUI")
local Nozzle = Handle:WaitForChild("Nozzle")
local Mouse = Player:GetMouse()
local UIS = game:GetService("UserInputService")

local Ammo = Config.Ammo
local MaxAmmo = Config.MaxAmmo

local CanShoot = true

local function UpdateUI()
	for i,v in pairs(GUI.Base.Ammo:GetChildren()) do
		if v:IsA("Frame") then
			v:Destroy()
		end
	end
	for i = 1, Ammo.Value do
		local B = Bullet:Clone()
		B.Parent = GUI.Base.Ammo
	end
end

local function ParentUI()
	if Gun.Parent == Player.Backpack then
		GUI.Parent = script
	else
		GUI.Parent = Player.PlayerGui
		UpdateUI()
	end
end

local function Reload()
	if Ammo.Value >= MaxAmmo.Value+1 then return end
	CanShoot = false
	GUI.Base.GName.Text = "Reloading..."
	wait(2)
	GUI.Base.GName.Text = Gun.Name
	if Ammo.Value > 0 then
		Ammo.Value = MaxAmmo.Value+1
	else
		Ammo.Value = MaxAmmo.Value
	end
	CanShoot = true
end

local function Shoot()
	if CanShoot then
		if Ammo.Value > 0 then
			Ammo.Value -= 1
			local Origin = Nozzle.WorldPosition
			local Direction = Mouse.Hit.Position-Origin
			local BulletRay = Ray.new(Origin,Direction)
			local Part,Position = workspace:FindPartOnRay(BulletRay,Gun,false,false)
			local OriginCF = CFrame.lookAt(Origin,Position)*CFrame.Angles(0,math.rad(-90),0)
			Gun.Visualize:FireServer(Part,Position,OriginCF)
		else
			Reload()
		end
	end
end

UIS.InputBegan:Connect(function(i,gpe)
	if not gpe then
		if i.KeyCode == Enum.KeyCode.C then
			Reload()
		end
	end
end)

Ammo.Changed:Connect(UpdateUI)
Gun.Activated:Connect(Shoot)
Gun:GetPropertyChangedSignal("Parent"):Connect(ParentUI)

Client