So I want to create a projectile algorithm for an upcoming project I have planned. I fully plan on using ray-casting to do so as it’s a weapon based projectile that’ll do damage to the players.
However, something I’m not very familiar with is the math that goes into calculating it’s path on an arc based system. (Which I regret not looking into at an earlier time.) I have created a rough chart how I wish for it to go.
If I was to shoot (or throw) a projectile about half of the maximum force from a platform 30 studs above the ground. It travels 75 studs in a straight line before hitting the ground and would be 80.8 Studs away from the player at a 21.8 Degree angle.
How should I go on achieving this?
Keep in mind that there is a force value involved onto how far and how fast the projectile would drop.
Albeit similar to what I am seeking. It’s not very precise in what I am trying to achieve.
This is mainly concerning the fact that I can’t figure out a way to implement the ‘force’ I explained in the OP. Another part would be over the fact that the bézier curve hub page, all the calculations are done using, 3, 4 or even multiple more points.
Which in what I’m trying to achieve, there are only two, the origin of the projectile and the position the player was aiming at. Having any more then those two wouldn’t be precisely ideal for me.
Hm, I’m wondering if using bezier curves, you could calculate a third point that would make a right angle connecting the other two points.
Basically, what I’m saying is if the origin line went up, and the click destination made a horizontal line perpendicular to the other line, the point where they intersect can be where the bezier curves gets its pull.
Just an idea though. I hope you find your solution!
Edit: Thinking a bit more, the point should be along the horizontal line (maybe halfway across from intersection to click destination) so it gets more of an “arcy” shape.
If this is a projectile being launched with some initial velocity, and subject only to gravity thereafter, Bézier curves are not what you need. The path of the projectile is parabolic, and described here: Equations of motion - Wikipedia The constant acceleration equation s(t) = s0 + v0t + 0.5at^2 gives the position s(t) at time t, given initial position s0 and initial launch velocity v0. The acceleration a is presumably just workspace gravity if you have no body force on the projectile.
Given a launch height (30), and desired horizontal distance (75 in your diagram), you can break this down into 2 different problems, separating the horizontal and vertical components. Solve your quadratic first for the time it takes to fall 30 studs with whatever your initial vertical velocity is (0 if shooting horizontal), then solve the simpler linear equation for horizontal velocity ( which will just be 75 divided by this time value).
It’s not typical to describe shooting something with a specific force, since a force needs to be applied over time. What you really want to know is the launch velocity. If this velocity is due to a force being applied for some amount of time, you need F=ma and the mass of your projectile to work out what velocity that force gets the projectile up to as your first step in all this (again with the equations of motion, but this time with a = F/m instead of gravity).
If you are trying to start with a known target position (given by a mouse click) and a preset magnitude for your initial velocity and work backwards to find the best launch angle and travel time,…[Deleted] Edited because the rest didn’t work out when I looked into it.
If you want to start with a known velocity (perhaps from the half-force you mentioned) and a target position you’re aiming at, you can find the launch angle with something like the following (which is ultimately what I was trying to get at earlier):
Something like this
local function QuadraticEq(a, b, c)
local sq = math.sqrt(b^2 - 4*a*c)
return {(-b + sq)/(2*a), (-b - sq)/(2*a)}
end
local g = workspace.Gravity -- gravity
local x = 30 -- distance to target
local y = -30 -- y displacement (amount of drop)
local s = 100 -- mag of initial vel (studs/sec)
local a = (-g*0.5*x^2)/(s^2)
local b = x
local c = a - y
local result = QuadraticEq(a,b,c)
-- one of these is the angle for firing right at the target and the other is for lob
print("DEGREE ANGLE1", math.deg(math.atan(result[1])))
print("DEGREE ANGLE2", math.deg(math.atan(result[2])))
The code is based on a version of this idea:
0 = x * tan(theta) - [(gx^2)/(2mag^2) * tan(theta)^2] + (gx^2)/(2mag^2) -y
where x is the dist between launcher and target, g is gravity, mag is the magnitude of the init velocity, y is the displacement in y (from launcher to elevation where projectile lands), and theta is the angle of the launcher (from horiz).
This is a quadratic that you solve for tan(theta), then take the atan of the solutions to get your angles. The two solutions are supposed to correspond to shooting directly at the target and lobbing (I stopped messing with it before I got my lobs working, so I can’t confirm that bit works).
In the vid I just launched bricks using part velocity. EmilyBendsSpace explained a better way to proceed when you’re ready to plot your path.
Can kind of see the angle adjusting in this bad vid from my slow machine.
Anyway, good luck with your project.
many years ago i had posed the same question to this devforum,
allow me to pass unto you the code passed unto me that day.
local base = script.Parent
local step = 0.1
local velocity = base.CFrame.lookVector * -300
local acceleration = Vector3.new(0,-workspace.Gravity,0)
local start = base.Position
local finish = start + velocity * step
local ignore = base.Parent
local H,P = workspace:FindPartOnRay(Ray.new(start, (finish-start)), ignore)
local i = 0
while H == nil and i < 50 do
local dt = wait(step)
velocity = velocity + acceleration * dt
finish = start + velocity * dt
H,P = workspace:FindPartOnRay(Ray.new(start, (finish-start)), ignore)
start = finish
i = i + 1
end
if H then
DoDamage()
end
unless you’re talking about animating on a path, in which case i’d just use an upside-down parabola