Raycast not getting result when it should

local tool = script.Parent
local handle = tool:WaitForChild("Handle")

script.Parent.Update.OnServerEvent:Connect(function(plr, hit)
	
	warn("bang")
	
	local muzzle = handle:WaitForChild("Muzzle")
	
	local rayOrigin = Vector3.new(muzzle.WorldPosition)
	local rayDirection = Vector3.new(hit.Position-handle.Position).Unit * 250 +Vector3.new(math.random(-30, 30), math.random(-30,30), math.random(-30, 30))

	local raycastResult = workspace:Raycast(rayOrigin, rayDirection)

	if raycastResult then
		print("Instance:", raycastResult.Instance)
		print("Position:", raycastResult.Position)
		print("Distance:", raycastResult.Distance)
		print("Material:", raycastResult.Material)
		print("Normal:", raycastResult.Normal)
		

		warn("hit")

		local distance = (rayOrigin - raycastResult.Position).Magnitude
		local p = Instance.new("Part")
		p.Anchored = true
		p.CanCollide = false
		p.Size = Vector3.new(0.1, 0.1, distance)
		p.CFrame = CFrame.lookAt(rayOrigin, raycastResult.Position)*CFrame.new(0, 0, -distance/2)

		p.Parent = game.Workspace
		
	
	else
		warn("No raycast result!")
	end
end)

The code should be correct but it doesn’t seen to return a raycast result. (most of it it from create.roblox)

Are you familiar with lookvectors and CFrames?

workspace:Raycast(origin, direction) takes in two arguments.
origin is a Vector3, which is the position of where the ray is firing from.
direction is also a Vector3, which is the direction of where the ray is going. If you multiply it with a number, that determines how far the raycast goes.

So let’s say I want to fire a raycast from the player’s head, in the direction the head is looking:

local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local head = character:WaitForChild("Head")
workspace:Raycast(head.Position, head.CFrame.LookVector * 500)

I’m trying to fire a raycast out of the barrel with the direction of the mouse. Lookvector wouldn’t work because there’s not an mouse.(whatever) that is a CFrame

mouse.UnitRay already returns a Vector3, so you don’t need to do any shenanigans with CFrame.

See if this makes any difference as you can’t feed a Vector3 as input to Vector3.new. It takes X, Y, and Z.

local tool = script.Parent
local handle = tool:WaitForChild("Handle")

script.Parent.Update.OnServerEvent:Connect(function(plr, hit)
	
	warn("bang")
	
	local muzzle = handle:WaitForChild("Muzzle")
	
	local rayOrigin = muzzle.Position
	local rayDirection = (hit.Position-handle.Position).Unit * 250 +Vector3.new(math.random(-30, 30), math.random(-30,30), math.random(-30, 30))

	local raycastResult = workspace:Raycast(rayOrigin, rayDirection)

	if raycastResult then
		print("Instance:", raycastResult.Instance)
		print("Position:", raycastResult.Position)
		print("Distance:", raycastResult.Distance)
		print("Material:", raycastResult.Material)
		print("Normal:", raycastResult.Normal)
		

		warn("hit")

		local distance = (rayOrigin - raycastResult.Position).Magnitude
		local p = Instance.new("Part")
		p.Anchored = true
		p.CanCollide = false
		p.Size = Vector3.new(0.1, 0.1, distance)
		p.CFrame = CFrame.lookAt(rayOrigin, raycastResult.Position)*CFrame.new(0, 0, -distance/2)

		p.Parent = game.Workspace
		
	
	else
		warn("No raycast result!")
	end
end)

Just be aware you might start hitting your own parts that you generate unless you use the raycast parameters and blacklist them.