Throwing function not working below a certain height

I am attempting to make a function where you’re able to throw a tool that you’re holding a certain distance. To that end, I have a function to generate a direction vector from a mouse click and another function to calculate the force behind the throw. One of the steps in calculating this force is cropping the direction vector to a maximum “throwing range” magnitude set by the tool. When I do this, however, the direction of the throw vector does not match the original direction vector below a certain point; if I attempt to throw it at the ground, it will instead throw the tool forward.

Below is a demonstration of the problem: the long gray line is the direction vector, the transparent gray cube is the end of the throw vector:

Looks correct, but if I try to throw it at the ground directly in front of me:

I don’t understand how this could be happening. The only transformation I’m making to the direction vector is capping it at a certain magnitude. The direction itself shouldn’t be changing at all.

Here is the code (the two important functions):

-- creates a ray to pass off as a projectile direction
local function generateRay(tool, origin)
	local direction
	local mousePosition = UIS:GetMouseLocation()
	local mouseRay = workspace.Camera:ViewportPointToRay(mousePosition.X, mousePosition.Y)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
	raycastParams.FilterDescendantsInstances = {tool.Parent}
	local raycastResult = workspace:Raycast(mouseRay.Origin, mouseRay.Direction * 1000, raycastParams)
	if raycastResult then
		direction = origin + (raycastResult.Position - origin)
	else
		direction = origin + mouseRay.Direction * 1000
	end
	local distance = direction.Magnitude
	local cFrame = CFrame.lookAt(origin, direction) * CFrame.new(0, 0, -distance / 2)
	local ray = Instance.new("Part")
	ray.Size = Vector3.new(0.2, 0.2, distance)
	ray.CFrame = cFrame
	ray.Anchored = true
	ray.CanCollide = false
	ray.Parent = workspace
	return direction
end
-- creates the arc for throwing
local function throw(tool, direction)
	if tool.ClassName ~= "Tool" then return end
	local throwVector
	if direction.Magnitude > RANGE then throwVector = direction.Unit * RANGE else throwVector = direction end
	local marker = Instance.new("Part", workspace)
	marker.Anchored = true
	marker.CanCollide = false
	marker.Transparency = 0.5
	marker.Size = Vector3.new(1, 1, 1)
	marker.Position = tool.Handle.Position + throwVector
	local duration = math.log(1.001 + throwVector.Magnitude * 0.01)
	local force = throwVector / duration + Vector3.new(0, workspace.Gravity * duration * 0.5, 0)
	local clone = tool.Handle:Clone()
	clone.CanCollide = true
	clone.Parent = workspace
	clone:ApplyImpulse(force * clone.AssemblyMass)
	print(throwVector, force, clone.AssemblyMass)
end

Please let me know if I need to provide any more information.

Looking through it, this variable name seems odd.

Its named direction however you have added origin to it a position vector, so it should actually become rayPosition instead.

This also means you cannot do .Unit and change the direction as well.

This only applies to direction vectors, if its applied to a position vector like adding origin it will rescale towards the origin point (0,0,0) and end up with some weird effects.

Therefore try removing origin from the direction variable.

Commenting out the additional origin basically reverses the results. Now when I aim above the horizon line, it works:

But if I aim below the horizon line, the direction vector seems to be wrong while the truncated throw vector seems to be right:


I mean, it does do what I want it to do, but are there going to be issues later down the line with how the direction vector now appears to be wrong?