I’m trying to use a Beam to visually represent a projectile’s trajectory, showing where it will land. The Beam is dynamically updated between two attachments (start position and target).
The issue I’m facing is that the CurveSize doesn’t accurately reflect the expected parabolic trajectory. Depending on the distance or angle, the curve generated by the Beam doesn’t align with the physics of the projectile.
I’m looking for advice on how to calculate CurveSize so that the Beam always matches the actual trajectory, considering factors like initial velocity, gravity, and direction.
Any guidance or suggestions for adjusting the calculation would be greatly appreciated!
local function onMaxDistance(v, g, d, h)
local m = h / d
local v2 = v * v
return (v2*math.sqrt(m*m + 1) - m*v2) / g
end
local function onLaunchAngle(v: number, g: number, d: number, h: number, higherArc: boolean): (boolean, number)
local max_x = onMaxDistance(v, g, d, h)
local v2 = v * v
if d > max_x then
return false, math.atan(v2 / (g * max_x))
end
local v4 = v2 * v2
local humanoidRootPart = math.sqrt(v4 - g*(g*d*d + 2*h*v2))
if not higherArc then humanoidRootPart = -humanoidRootPart end
return true, math.atan((v2 + humanoidRootPart) / (g * d))
end
local function onLaunchDirection(start, target, v, g, higherArc: boolean)
local horizontal = Vector3.new(target.X - start.X, 0, target.Z - start.Z)
local h = target.Y - start.Y
local d = horizontal.Magnitude
local inRange, a = onLaunchAngle(v, g, d, h, higherArc)
local vec = horizontal.Unit * v
local rotAxis = Vector3.new(-horizontal.Z, 0, horizontal.X)
return inRange, CFrame.fromAxisAngle(rotAxis, a) * vec
end
local function onUpdateTrajectory()
local start = humanoidRootPart.CFrame
--local target = workspace:WaitForChild("Target").Position
local target = mouse.Hit.Position
local horizontal = Vector3.new(target.X - start.X, 0, target.Z - start.Z)
local gravity = workspace.Gravity
local h = target.Y - start.Y
local d = horizontal.Magnitude
local IsRange, test = onLaunchAngle(velocity, gravity, d, h, higher)
local IsRange, dir = onLaunchDirection(start, target, velocity, gravity, higher)
local curveSize = workspace.Adjust.Value * test * dir.Magnitude
Beam.CurveSize0 = curveSize > 0 and curveSize or 1
Beam.CurveSize1 = curveSize > 0 and -curveSize or .5
Attach0.CFrame = start * CFrame.Angles(0,0,math.rad(90))
Attach1.CFrame = mouse.Hit * CFrame.new(0, workspace.StudsY.Value, 0) * CFrame.Angles(0,0,math.rad(90))
local p = Instance.new("Part")
p.Size = Vector3.new(1, 1, 1)
p.CanCollide = false
p.BrickColor = IsRange and BrickColor.Green() or BrickColor.Red()
p.Position = humanoidRootPart.Position
p.Velocity = dir
p.Parent = workspace.Framework.Parts
Debris:AddItem(p, 1)
end