I'm making a gun. But a big gameplay issue is the ability to put the gun through a part, and be able to shoot out the other side. I'm using raycast here is my script. It's a local script btw.

local tool = script.Parent
local user
local cooldown = false
local ammo = 18
local debounce = false
local canfire = true
tool.Equipped:connect(function(mouse)
	user = tool.Parent
	mouse.Button1Down:connect(function()
		if cooldown == false and ammo > 0 and canfire == true then
			ammo = ammo - 1
			tool.Handle.Fire:Play()
			tool.Name = "|Pistol| ["..ammo.."]"
			cooldown = true
			local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - tool.Handle.CFrame.p).unit*300)
			local hit, position = game.Workspace:FindPartOnRay(ray, user)
			local humanoid = hit and hit.Parent and hit.Parent:FindFirstChild("Humanoid")
		    if humanoid then
				if hit.Name == "Head" then
					humanoid:TakeDamage(55)
				end
				if hit.Name == "LeftLeg" or hit.Name == "RightLeg" then
					humanoid:TakeDamage(10)
				end
				if hit.Name == "LeftArm" or hit.Name == "RightArm" then
					humanoid:TakeDamage(10)
				end
		    	humanoid:TakeDamage(30)
		    end
			
			local distance = (position - tool.Handle.CFrame.p).magnitude
		    local rayPart = Instance.new("Part", user)
		    rayPart.Name          = "RayPart"
		    rayPart.BrickColor    = BrickColor.new("Bright red")
		    rayPart.Transparency  = 0.5
		    rayPart.Anchored      = true
		    rayPart.CanCollide    = false
		    rayPart.TopSurface    = Enum.SurfaceType.Smooth
		    rayPart.BottomSurface = Enum.SurfaceType.Smooth
		    rayPart.formFactor    = Enum.FormFactor.Custom
		    rayPart.Size          = Vector3.new(0.2, 0.2, distance)
		    rayPart.CFrame        = CFrame.new(position, tool.Handle.CFrame.p) * CFrame.new(0, 0, -distance/2)
			game.Debris:AddItem(rayPart, 0.1)
		end
		if ammo == 0 then
			if debounce == false then
				debounce = true
				tool.Name = "Reloading"
				tool.Handle.Reload:Play()
				wait(2.5)
				ammo = 18
				tool.Name = "|Pistol| ["..ammo.."]"
				debounce = false
			end
		end
		mouse.KeyDown:connect(function(key)
			if key == "r" and debounce == false then
				debounce = true
				tool.Name = "Reloading"
				tool.Handle.Reload:Play()
				wait(2.5)
				ammo = 18
				tool.Name = "["..ammo.."]"
				debounce = false
			end
		end)
	end)
end)
while true do
	if cooldown == true then
		wait(0.25)
		cooldown = false
	end
	
	wait()
end