Raycast gun not working correctly

I have this gun system that creates a beam and adds it to a raycast. But it is sometimes not showing or is being stopped from nothing which you can see in the video below.

ServerScript:

revRE.OnServerEvent:Connect(function(player, tool, startPosition, endPosition)
	task.spawn(function()
		local character = player.Character
		local bodyEffects = character:WaitForChild("BodyEffects")
		local reload = bodyEffects:WaitForChild("Reload")
		local barrel = tool.Barrel
		local handle = tool.Handle
		local range = tool:WaitForChild("Range").Value	
		
		local beamDisappearTime = 0.45

		if bodyEffects:WaitForChild('Ragdolled').Value then return end

		if tool.Ammo.Value >= 1 then
			local GUI = player:WaitForChild("PlayerGui"):WaitForChild("Weapons"):WaitForChild("Revolver")
			local GoingToShootBullet = GUI:WaitForChild("MainFrame"):FindFirstChild("BulletImage")

			if GoingToShootBullet then
				GoingToShootBullet.ImageTransparency = 0.6
				GoingToShootBullet.Name = "UsedBullet"

				if not reload.Value then
					reload.Value = true

					barrel.ShootUI.Shoot.ImageTransparency = 0.6
					barrel.ShootUI.Shoot.Visible = true
					handle.ShootLight.Enabled = true

					local Shoot = Instance.new("Sound")	
					Shoot.SoundId = "rbxassetid://1583819337"
					Shoot.Parent = handle
					Shoot:Play()

					local StartPoint = Instance.new("Part")
					StartPoint.Transparency = 1
					StartPoint.Parent = workspace:WaitForChild("Ignore")
					StartPoint.Position = startPosition
					StartPoint.Size = Vector3.new(0.5, 0.5, 0.5)
					StartPoint.Anchored = true
					StartPoint.CanCollide = false

					local EndPoint = Instance.new("Part")
					EndPoint.Transparency = 1
					EndPoint.Parent = workspace:WaitForChild("Ignore")
					EndPoint.Position = endPosition
					EndPoint.Size = Vector3.new(0.5, 0.5, 0.5)
					EndPoint.Anchored = true
					EndPoint.CanCollide = false	

					local attachment1 = Instance.new("Attachment")
					local attachment2 = Instance.new("Attachment")
					attachment1.Parent = StartPoint
					attachment2.Parent = EndPoint

					local beam = Instance.new("Beam")
					beam.Color = ColorSequence.new({
						ColorSequenceKeypoint.new(0, Color3.fromRGB(255, 170, 0)),
						ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 255, 127)),
					})
					beam.LightEmission = 1
					beam.Attachment1 = attachment2
					beam.Attachment0 = attachment1
					beam.Width0 = 0.002
					beam.Width1 = 0.09
					beam.FaceCamera = true
					beam.Transparency = NumberSequence.new(0)
					beam.Parent = StartPoint

					local raycastDirection = (endPosition - startPosition).Unit * range

					local raycastParams = RaycastParams.new()
					raycastParams.FilterDescendantsInstances = {character, tool, tool.Barrel, workspace:WaitForChild("Ignore"):GetChildren()}
					raycastParams.FilterType = Enum.RaycastFilterType.Exclude

					local raycast = workspace:Raycast(startPosition, raycastDirection, raycastParams)

					if raycast then 
						local hitCharacter = raycast.Instance:FindFirstAncestorWhichIsA("Model")

						if hitCharacter then
							local humanoid = hitCharacter:FindFirstChild("Humanoid")

							if humanoid then 
								if not humanoid.Parent:WaitForChild("BodyEffects"):WaitForChild("Ragdolled").Value then 
									local distance = (endPosition - startPosition).Magnitude
									local bloodParticle = script.Parent.Parent:WaitForChild("BloodParticle"):Clone()
									local hitPlayer = players:GetPlayerFromCharacter(humanoid.Parent)
									local originOfDamage = character:WaitForChild("HumanoidRootPart").Position

									bloodParticle.Parent = raycast.Instance
									task.delay(0.5, function()
										bloodParticle:Destroy()
									end)

									if distance <= 5 then
										damagePlayer(humanoid, 28)
									else
										damagePlayer(humanoid, 20)
									end

									if humanoid.Parent.Parent == workspace:WaitForChild("Alive") then
										damageRE:FireClient(hitPlayer, originOfDamage)
									end
								end
							end
						end
					end

					task.wait(0.1)
					reload.Value = false
					barrel.ShootUI.Shoot.Visible = false
					handle.ShootLight.Enabled = false

					for i = 0, 100, wait() / beamDisappearTime do --put to 100 to show issue
						beam.Transparency = NumberSequence.new(0 + (1 - 0) * i)
						task.wait()
					end
					beam.Transparency = NumberSequence.new(1)

					beam:Destroy()
					attachment1:Destroy()
					attachment2:Destroy()
					StartPoint:Destroy()
					EndPoint:Destroy()

					Shoot.Ended:Wait()
					Shoot:Destroy()
				end
			else
				if bodyEffects:WaitForChild('Ragdolled').Value then return end

				handle.NoAmmo:Play()
			end
		end
	end)
end)

Does it not show only if you shoot at the skybox? If so, it’s because it hit nothing and and returned no position. You might need to write extra code with math to determine where the ray ended for a fallback.

1 Like