So if you know basics of aviation, further something is the higher the object needs to go up in the sky.
So I am trying to make a brick lerp to the objective which already works as I use bodymover in lookvector to speed it up and lerp to rotate it to the object but is there a way to calculate the distance between the objects and then calculate the desired angle or something?
I don’t understand what you’re asking, sorry. Could you clarify a bit?
This is targeting coordinates btw but I’m not sure how to achieve this without elevating the brick higher than the destination coordinates
Maybe I’m just dumb, but I don’t understand what you’re trying to say with those two pictures.
At a high level, what are you trying to do? Are you making a catapult and you want to figure out launch angle and speed or something?
I need the brick to fly up in the air not go basically straight to the point when on similar height
OK, so you’re making a catapult?
You have some speed that you want the projectile to go, and you want to know the angle to launch it at, is that correct?
The speed is a set amount but the object will get the angle to look at in the air and then will slowly turn to the object’s position
This ended being kinda fun.
A bezier curve might work for this: BĂ©zier curve - Wikipedia
It’s this:
Where P0 is the starting point, P2 is the target, and P1 is just some value we choose that’s, say, ten studs above the midpoint between the start and end.
Stealing some equations from wikipedia for the equation of the tangent… and… done.
-
Put a Part in workspace and put this in a LocalScript in StarterPlayerScripts or something.
-
Test the game and click around.
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local part = workspace:WaitForChild("Part")
local Fire
do
local UP = Vector3.new(0, 1, 0)
local conn
function Fire(part, start, target, duration, heightControl)
-- default parameters
if not duration then duration = 1 end
if not heightControl then heightControl = 10 end
-- bezier calcs
local control = (start + target) / 2 + Vector3.new(0, heightControl, 0)
local ab = control - start
local bc = target - control
-- will move this from 0 to 1
local t = 0
-- kill any previous movement
if conn then conn:Disconnect() end
-- and start a new one
conn = game:GetService("RunService").Stepped:Connect(function(_, dt)
-- increment t by a bit
t += dt / duration
if t > 1 then
-- reached the end
t = 1
conn:Disconnect()
conn = nil
end
-- bezier equations from https://en.wikipedia.org/wiki/Bezier_curve
local pos = (1-t)*(1-t)*start + 2*(1-t)*t*control + t*t*target
local dir = (2*(1-t)*ab + 2*t*bc).Unit
-- compute CFrame based on right vector and direction vector
-- TODO handle the case where target is right above start
local right = (target-start).Unit:Cross(UP)
part.CFrame = CFrame.fromMatrix(pos, right, right:Cross(dir), -dir)
end)
end
end
mouse.Button1Down:Connect(function()
Fire(part, part.Position, mouse.Hit.p)
end)
The Fire
function takes 3-5 parameters.
Caveats:
- This doesn’t follow physics. If you’re trying to use this to represent a projectile, there are more accurate ways. For visualization of like a plane (which I’m guessing is what you’re doing) it’s probably fine.
- The speed along the curve is not exactly consistent for reasons. But I think it’s fine.
- It takes a “duration” parameter rather than a “speed” parameter. You can get closer to a “speed” by setting
duration = (target-start).Magnitude / studsPerSecond
, but that won’t be exact. Computing the length of the curve itself is hard.