# How To Get Trajectory Path Of A Projectile's Velocity (Or Just A Vector3 Force)?

I cannot seem to figure out the math behind calculating the trajectory of velocity.

I should note that (at least for my case) the velocity- or namely ‘Force’, is perfectly fine and works in every case I’ve tested it in. My issue arises in the `Project` function.

The whole code:

``````local function Project(Force: Vector3, Origin: Vector3, Goal: Vector3)
local Points = {}
for Time = 0, 1, .1 do
--// Suspected culprit
local Point = Origin + (Force * Time)
Point = Vector3.new(Point.X,
Origin.Y + (Force.Y * Time) - ((workspace.Gravity / 2) * Time * Time),
Point.Z)
--//
table.insert(Points, Point)
end

return Points
end

--// Simple parts in studio, projectile is just a ball
local Origin, Goal, Projectile = workspace.Start.Position, workspace.End.Position, workspace.Projectile

local function GetForceNeeded(Origin: Vector3, Goal: Vector3, Projectile: BasePart?, MaxDistance: number?): Vector3

local Distance = (Goal - Origin).Magnitude
MaxDistance = MaxDistance and math.min(MaxDistance, Distance) or Distance

local Direction = Goal - Origin
local Duration = math.log(1.001 + Direction.Magnitude * 0.01)
local Force = Direction.Unit * MaxDistance / Duration + Vector3.new(0, workspace.Gravity * Duration * 0.5, 0)

return Projectile and Force * Projectile.AssemblyMass or Force
end

local MaxDistance = (Goal - Origin).Magnitude

local Force = GetForceNeeded(Origin, Goal, Projectile, MaxDistance)

local Points = Project(Force, Origin, Goal)

for _, Point in pairs(Points) do

local Part = Instance.new("Part")
Part.Anchored = true
Part.CanCollide = false
Part.Size = Vector3.one
Part.Color = Color3.fromRGB(255, 170, 0)

Part.CFrame = CFrame.new(
Point
)

Part.Parent = workspace
end

...

--// Force is applied to Projectile part as :ApplyImpulse( Force )
``````

Another important note is I am not using Bezier Curves or anything like that because AFAIK this is different as it’s actual physics. Correct me if I’m wrong though!

Result I’m trying to achieve:
https://gyazo.com/1543a8dfa9fc5ef6683a5fd8c082903e

1 Like

Hey! I wish I knew how to pinpoint what to do in order to exactly achieve this. But your question reminded me of a video I watched that seems almost exactly similar to what you’re trying to do except this person uses tweens to reach his curved points. Hopefully you find this useful enough to be capable of implementing it to your liking!

If you have time to watch this, it may be beneficial. It’s 42 minutes long btw.

1 Like

Turns out it in-fact was the Force factor. It returned `Force * AssemblyMass` which altered the passed Force in `Project` function that was completely throwing off the calculations.

Updated code:

``````local function Project(Force: Vector3, Origin: Vector3): {Vector3}
local Points = {}
for Time = 0, 1, .1 do
local Point = Origin + (Force * Time)
Point = Vector3.new(Point.X,
Origin.Y + (Force.Y * Time) - ((workspace.Gravity / 2) * Time * Time),
Point.Z)

table.insert(Points, Point)
end

return Points
end

--// Simple parts in studio, projectile is just a ball
local Origin, Goal, Projectile = workspace.Start.Position, workspace.End.Position, workspace.Projectile

local function GetForceNeeded(Origin: Vector3, Goal: Vector3, Projectile: BasePart?, MaxDistance: number?): Vector3

local Distance = (Goal - Origin).Magnitude
MaxDistance = MaxDistance and math.min(MaxDistance, Distance) or Distance

local Direction = Goal - Origin
local Duration = math.log(1.001 + Direction.Magnitude * 0.01)
local Force = Direction.Unit * MaxDistance / Duration + Vector3.new(0, workspace.Gravity * Duration * 0.5, 0)

return Force --// Projectile and Force * Projectile.AssemblyMass or Force (This caused issues in trajectory projection calculations
end

local MaxDistance = (Goal - Origin).Magnitude

local Force = GetForceNeeded(Origin, Goal, Projectile, MaxDistance)

local Points = Project(Force, Origin, Goal)

for _, Point in pairs(Points) do

local Part = Instance.new("Part")
Part.Anchored = true
Part.CanCollide = false
Part.Size = Vector3.one
Part.Color = Color3.fromRGB(255, 170, 0)

Part.CFrame = CFrame.new(
Point
)

Part.Parent = workspace
end

...

--// Force is applied to Projectile part as :ApplyImpulse( Force * AssemblyMass )
``````

Thank y’all for the help and additional resources!

# This is for people that are wondering what he exactly did:

It looks like your code is attempting to calculate the trajectory of a projectile given an initial position (`Origin` ), a target position (`Goal` ), and the properties of the projectile (such as mass and gravity). The suspected culprit you mentioned is likely related to the calculation of the trajectory points.

``````local function Project(Force: Vector3, Origin: Vector3, Goal: Vector3)
local Points = {}
for Time = 0, 1, .1 do
local Point = Origin + (Force * Time)
Point = Vector3.new(Point.X,
Origin.Y + (Force.Y * Time) - ((workspace.Gravity / 2) * Time * Time),
Point.Z)
table.insert(Points, Point)
end
return Points
end
``````

The suspected culprit section seems to be the adjustment of the Y-coordinate of the `Point` . This adjustment takes into account the effect of gravity over time. However, the term `((workspace.Gravity / 2) * Time * Time)` seems to be incorrect. The correct formula for vertical displacement due to gravity is `0.5 * g * t^2` , where `g` is the acceleration due to gravity. It should be `0.5 * workspace.Gravity * Time * Time` .

``````Origin.Y + (Force.Y * Time) - (0.5 * workspace.Gravity * Time * Time)
``````
``````local function GetForceNeeded(Origin: Vector3, Goal: Vector3, Projectile: BasePart?, MaxDistance: number?): Vector3
-- ...
end
``````

It calculates the force needed to reach the goal, taking into account the direction, distance, and gravity.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.