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!

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!

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 .