Why are my rays casting straight down?

So right now im making a C4 throwing system for my game civilized but the ray keeps casting down (vid below)
https://streamable.com/l7yojh
heres my script

local C4 = script.Parent.C4
local config = script.Parent.Config
local Vel = config.Drop.Value
local Drop = config.Vel.Value
local beam1
function findcollisions(Root, Torso, up)
	local table1 = {Root, Torso, up}
	for i,v in pairs(game.Workspace:GetDescendants()) do
		if v:IsA("BasePart") then
			if v.CanCollide == false then
				table.insert(table1, v)
			end
		end
	end
	print(table1)
	return table1
end
script.Parent.Throw.OnServerEvent:Connect(function(player, Pos)
	local clone = script.Parent.C4:Clone()
	clone.Parent = workspace
	print(Pos)
	print("Sarting")
	local head = player.Character.Head
	print((Pos - head.CFrame.p).unit + Vector3.new(90,0,0))
	local ignore = findcollisions(player.Character.HumanoidRootPart, player.Character.UpperTorso, player.Character.LowerTorso)
	local shotVel = {}
	shotVel[1] = Vel
	local drop = {}
	drop[1] = Drop
	local mousehit = Pos
	local hole = head
	local ray = Ray.new(head.CFrame.p, (head.Position - Pos).unit * shotVel[1])
	local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray,ignore)
	local oldpos = position
	if hit == nil then
		repeat
			print("Continueing")
			shotVel[1] = (shotVel[1] - .05)
			drop[1] = (drop[1] + .1)
			local ray = Ray.new(oldpos, (oldpos - mousehit).unit * shotVel[1] + Vector3.new(0,-drop[1],0))
			local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray,ignore)
			beam1 = Instance.new("Part", workspace)
			beam1.BrickColor = BrickColor.new("Cyan")
			beam1.FormFactor = "Custom"
			beam1.Material = "Neon"
			beam1.Transparency = 0.25
			beam1.Anchored = true
			beam1.Locked = true
			beam1.CanCollide = false
			local distance = (oldpos - position).magnitude
			beam1.Size = Vector3.new(0.3, 0.3, distance)
			beam1.CFrame = CFrame.new(oldpos, position) * CFrame.new(0, 0, -distance / 2)
			oldpos = position
			clone.Position = oldpos
			print(hit.Name)
		until
		hit ~= nil
	else 
		print("Hit")
		local clone = C4:Clone()
		clone.Parent = workspace
		clone.CFrame = CFrame.new(position, position + normal)
	end
end)

ive tried to fix this by using head.CFrame.lookvector but that gives the same results.
please help thanks in advance!

1 Like

This probably doesn’t have anything to do with your problem, but I’d like to point out that we’re not supposed to use Ray.new anymore.
We should be using workspace:Raycast()

1 Like

Did you mean CFrame.new(Head.Position, Pos).LookVector?

it still has the same result as before

The first ray fires right but the second goes straight down
https://streamable.com/a7ha9e
current code

local C4 = script.Parent.C4
local config = script.Parent.Config
local Vel = config.Drop.Value
local Drop = config.Vel.Value
local beam1
function findcollisions(Root, Torso, up)
	local table1 = {Root, Torso, up, script.Parent}
	for i,v in pairs(game.Workspace:GetDescendants()) do
		if v:IsA("BasePart") then
			if v.CanCollide == false then
				table.insert(table1, v)
			end
		end
	end
	return table1
end
script.Parent.Throw.OnServerEvent:Connect(function(player, Pos)
	local clone = script.Parent.C4:Clone()
	clone.Parent = workspace
	print("Sarting")
	local head = player.Character.FirePart
	print(head.Position)
	print(Pos)
	print(CFrame.new(head.Position, Pos).LookVector)
	local ignore = findcollisions(player.Character.HumanoidRootPart, player.Character.UpperTorso, player.Character.LowerTorso)
	local shotVel = {}
	shotVel[1] = Vel
	local drop = {}
	drop[1] = Drop
	local mousehit = Pos
	local hole = head
	local ray = Ray.new(head.CFrame.p, CFrame.new(head.Position, Pos).LookVector * shotVel[1])
	local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray,ignore)
	beam1 = Instance.new("Part", workspace)
	beam1.BrickColor = BrickColor.new("Really red")
	beam1.FormFactor = "Custom"
	beam1.Material = "Neon"
	beam1.Transparency = 0.25
	beam1.Anchored = true
	beam1.Locked = true
	beam1.CanCollide = false
	local distance = (head.Position - position).magnitude
	beam1.Size = Vector3.new(0.3, 0.3, distance)
	beam1.CFrame = CFrame.new(head.Position, position) * CFrame.new(0, 0, -distance / 2)
	local oldpos = position
	print(hit)
	if hit == nil then
		repeat
			print("Continueing")
			shotVel[1] = (shotVel[1] - .05)
			drop[1] = (drop[1] + .1)
			local ray1 = Ray.new(oldpos, (oldpos - Pos).unit * shotVel[1] + Vector3.new(0,-drop[1],0))
			local hit1, position1, normal1 = workspace:FindPartOnRayWithIgnoreList(ray1,ignore)
			beam1 = Instance.new("Part", workspace)
			beam1.BrickColor = BrickColor.new("Cyan")
			beam1.FormFactor = "Custom"
			beam1.Material = "Neon"
			beam1.Transparency = 0.25
			beam1.Anchored = true
			beam1.Locked = true
			beam1.CanCollide = false
			local distance = (oldpos - position1).magnitude
			beam1.Size = Vector3.new(0.3, 0.3, distance)
			beam1.CFrame = CFrame.new(oldpos, position1) * CFrame.new(0, 0, -distance / 2)
			oldpos = position
			clone.Position = oldpos
			if hit1 then
				print(hit1.Name)
				print("FINISHED")
				clone:Destroy()
				local clone = C4:Clone()
				clone.Parent = workspace
				clone.CFrame = CFrame.new(position1, position1 + normal1)
			end
		until
		hit1 ~= nil
	else 
		print("Hit")
		local clone = C4:Clone()
		clone.Parent = workspace
		clone.CFrame = CFrame.new(position, position + normal)
	end
end)

What are the values of the config? I assume the input to the Throw function is the mouse position and that works correctly.

You are taking a unit direction vector and multiplying it by a magnitude (as you should), but then adding on a separate vector for drop. Instead change the direction, get the unit, and multiply it by speed. Or maintain the velocity and change the xyz components each iteration for gravity and drag.

local direction = (endPos - startPos)
local velocity = direction*speed
repeat
    velocity = Vector3.new(velocity.X*0.95, velocity.Y*0.95 - drop, velocity.Z*0.95)
until hit

You accidently exchanged the declarations here. Since the rays are being cast directly downwards, is config.Drop.Value and in turn Vel 0?

(oldpos - Pos) will be a vector from Pos to oldpos and hence its unit vector will be the opposite direction, unless shotVel[1] oddly happens to be negative.

config.Drop.Value = 0.10000000000000000555

drop = 0.10000000000000000555
and
vel = 30

i tried that and it sort of worked (vid below) but the projectile slows down just before hitting the target
https://streamable.com/7teapx

local C4 = script.Parent.C4
local config = script.Parent.Config
local Vel = config.Drop.Value
local Drop = config.Vel.Value
local beam1
function findcollisions(Root, Torso, up)
	local table1 = {Root, Torso, up, script.Parent}
	for i,v in pairs(game.Workspace:GetDescendants()) do
		if v:IsA("BasePart") then
			if v.CanCollide == false then
				table.insert(table1, v)
			end
		end
	end
	return table1
end
script.Parent.Throw.OnServerEvent:Connect(function(player, Pos)
	local clone = script.Parent.C4:Clone()
	clone.Parent = workspace
	print("Sarting")
	local head = player.Character.Head
	local ignore = findcollisions(player.Character.HumanoidRootPart, player.Character.UpperTorso, player.Character.LowerTorso)
	local shotVel = {}
	shotVel[1] = Vel
	local drop = {}
	drop[1] = Drop
	local mousehit = Pos
	local hole = head
	local ray = Ray.new(head.CFrame.p, CFrame.new(head.Position, Pos).LookVector * shotVel[1])
	local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray,ignore)
	local oldpos = position
	print(hit)
	if hit == nil then
		repeat
			wait()
			shotVel[1] = (shotVel[1] - .05)
			drop[1] = (drop[1] + .1)
			local direction = (Pos - oldpos)
			local velocity = direction*shotVel[1]
			velocity = Vector3.new(velocity.X, velocity.Y - drop[1], velocity.Z)
			local ray1 = Ray.new(oldpos, velocity * shotVel[1])
			local hit1, position1, normal1 = workspace:FindPartOnRayWithIgnoreList(ray1,ignore)
			beam1 = Instance.new("Part", workspace)
			beam1.BrickColor = BrickColor.new("Cyan")
			beam1.FormFactor = "Custom"
			beam1.Material = "Neon"
			beam1.Transparency = 0.25
			beam1.Anchored = true
			beam1.Locked = true
			beam1.CanCollide = false
			local distance = (oldpos - position1).magnitude
			beam1.Size = Vector3.new(0.3, 0.3, distance)
			beam1.CFrame = CFrame.new(oldpos, position1) * CFrame.new(0, 0, -distance / 2)
			beam1:Destroy()
			oldpos = position1
			clone.Position = oldpos
			if hit1 then
				print(hit1.Name)
				print("FINISHED")
				clone:Destroy()
				local clone = C4:Clone()
				clone.Parent = workspace
				clone.CFrame = CFrame.new(position1, position1 + normal1)
			end
		until
		hit1 ~= nil
	else 
		print("Hit")
		local clone = C4:Clone()
		clone.Parent = workspace
		clone.CFrame = CFrame.new(position, position + normal)
	end
end)

From a physics perspective, velocity is a direction and speed, direction is a unit vector, and speed is a number. You stated velocity = direction*speed then later multiplied velocity by speed again. Remove the second time you have shotVel[1] (which is speed).
local ray1 = Ray.new(oldpos, velocity)
I don’t know if you were trying to make a realistic arc or not. If you do as I suggested, you just have to make sure your units line up. It helps if do this consistently which would also mean knowing the time for each step and adding it to your calculation.

Here is an example of how I would accomplish this.

local speed = 30 --studs per second
local acceleration = Vector3.new(0, -98.1, 0) --studs pre second per second
local timeLimit = 10 --In case the ray is shot into the void

local ignore = Instance.new("Folder", workspace)
function drawBeam(startPos, endPos)
	local beam1 = Instance.new("Part")
	beam1.BrickColor = BrickColor.new("Cyan")
	beam1.FormFactor = "Custom"
	beam1.Material = "Neon"
	beam1.Transparency = 0.25
	beam1.Anchored = true
	beam1.Locked = true
	beam1.CanCollide = false
	local distance = (endPos - startPos).magnitude
	beam1.Size = Vector3.new(0.3, 0.3, distance)
	beam1.CFrame = CFrame.new(startPos, endPos) * CFrame.new(0, 0, -distance / 2)
	beam1.Parent = ignore
end
local rayCastParams = RaycastParams.new()
rayCastParams.FilterType = Enum.RaycastFilterType.Blacklist
rayCastParams.FilterDescendantsInstances = {ignore, }

function throw(startPos, targetPos)
	local velocity = (targetPos - startPos).Unit*speed
	
	local lastPosition = startPos
	local timePos = 0
	local connection
	connection = game["Run Service"].Heartbeat:Connect(function(dt)
		timePos = timePos + dt
		if timePos >= timeLimit then
			timePos = timeLimit
			connection:Disconnect()
			--No parts were hit in the time limit. Place C4 anyway?
		end
		local newPosition = startPos + velocity*timePos + 0.5*acceleration*timePos^2
		drawBeam(lastPosition, newPosition)
		local result = workspace:Raycast(lastPosition, (newPosition - lastPosition), rayCastParams)
		if result then
			connection:Disconnect()
			--Plant C4 at result.Position
		end
		lastPosition = newPosition
	end)
end	

wait(2)
throw(Vector3.new(0,20,0), Vector3.new(10,20,0))

this script works like charm thank you B)