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.