How do I make a rocket point towards its trajectory?

Hello, as said in the title, I want to have my rocket launch in the same way that ICBM missiles do.


Here’s a gif for reference: https://i.makeagif.com/media/11-20-2015/FHLbQ_.mp4
Another gif: https://preview.redd.it/y5rie2n7bvw61.gif?width=728&format=mp4&s=083fd4062b269c0c51a98b63126da333dc9c43e7


To do this, I am using a quadratic Bézier curve. Although the movement part is as I want it to be, the rotation of the rocket doesn’t really match up with what I want.

Here is an image of how I want it to move (with the green arrows being its rotation):
image


Sadly, this is what happens in-game:


The missile’s position changes as intended, but not its rotation.
I tried making it look at the position that would follow after it (so the rotation would follow the curve), but that didn’t work either.


Here is my script:

--// Variables

local Points = workspace.Points

local MovingPart = workspace:WaitForChild("Rocket")

local updateFrequency = 100
local refreshRate = 1/updateFrequency

--// Functions

function Linear(p0, p1, t)	
-- Linear interpolation
	return (1-t)*p0 + t*p1
end

function Quadratic(p0, p1, p2, t)
-- Quadratic interpolation
	return (1-t)^2*p0 + 2*(1-t)*t*p1 + t^2*p2
end

while task.wait() do
-- Test function
	for i = 1, updateFrequency do 
		-- Times
		local tNow = i/updateFrequency 
		local tFuture = tNow + refreshRate
		
		if tFuture > 1 then tFuture = 1 end
		
		-- Points 
		local Start = Points.p0.Position
		local Top = Points.p1.Position
		local End = Points.p2.Position
		
		-- Positions
		local updatedPosition = Quadratic(Start, Top, End, tNow)
		local futurePosition = Quadratic(Start, Top, End, tFuture)
		
		MovingPart.Position = updatedPosition
		MovingPart.CFrame = CFrame.lookAt(updatedPosition, futurePosition) -- points at the position that is ahead
		
		task.wait(refreshRate)
	end
end

Thanks in advance for your help.

--// Variables
local Points = workspace.Points

local MovingPart = workspace:WaitForChild("Rocket")

local updateFrequency = 100
local refreshRate = 1 / updateFrequency

--// Functions
function Linear(p0, p1, t)
    -- Linear interpolation
    return (1 - t) * p0 + t * p1
end

function Quadratic(p0, p1, p2, t)
    -- Quadratic interpolation
    return (1 - t)^2 * p0 + 2 * (1 - t) * t * p1 + t^2 * p2
end

-- Main loop
while task.wait() do
    -- Test function
    for i = 1, updateFrequency do
        -- Times
        local tNow = i / updateFrequency 
        local tFuture = tNow + refreshRate
        
        if tFuture > 1 then tFuture = 1 end
        
        -- Points 
        local Start = Points.p0.Position
        local Top = Points.p1.Position
        local End = Points.p2.Position
        
        -- Positions
        local updatedPosition = Quadratic(Start, Top, End, tNow)
        local futurePosition = Quadratic(Start, Top, End, tFuture)
        
        -- Update position and orientation
        MovingPart.Position = updatedPosition
        MovingPart.CFrame = CFrame.lookAt(updatedPosition, futurePosition) -- points at the position that is ahead
        
        task.wait(refreshRate)
    end
end

If you’re still having this issue, you can just add a Rotation offset or whatever they’re called.

--// Variables

local Points = workspace.Points

local MovingPart = workspace:WaitForChild("Rocket")

local Rotation = CFrame.Angles(0, math.rad(90), 0) -- Modify this if it's not rotated the right way

local updateFrequency = 100
local refreshRate = 1/updateFrequency

--// Functions

function Linear(p0, p1, t)	
	-- Linear interpolation
	return (1-t)*p0 + t*p1
end

function Quadratic(p0, p1, p2, t)
	-- Quadratic interpolation
	return (1-t)^2*p0 + 2*(1-t)*t*p1 + t^2*p2
end

while task.wait() do
	-- Test function
	for i = 1, updateFrequency do 
		-- Times
		local tNow = i/updateFrequency 
		local tFuture = tNow + refreshRate

		if tFuture > 1 then tFuture = 1 end

		-- Points 
		local Start = Points.p0.Position
		local Top = Points.p1.Position
		local End = Points.p2.Position

		-- Positions
		local updatedPosition = Quadratic(Start, Top, End, tNow)
		local futurePosition = Quadratic(Start, Top, End, tFuture)

		MovingPart.Position = updatedPosition
		MovingPart.CFrame = CFrame.lookAt(updatedPosition, futurePosition) * Rotation -- points at the position that is ahead

		task.wait(refreshRate)
	end
end
1 Like

Hey,

Thanks a lot for your reply, that did fix the issue.
But I do have a couple of questions, if you wouldn’t mind:

  1. Why does multiplying it by that Rotation y-value work?

  2. Is it possible to achieve the same thing that I did with the Bézier curve, with a normal quadratic function with formula y = a(x-A)² + B?
    I’m asking this because with a Bézier curve you can’t really set the max height that you want it to fly towards

  3. Is it possible to add a max speed?
    With a Bézier curve, the velocity of the movement depends on how far apart the points are; if they’re really far apart, the rocket will go really fast, if they’re really close, then it’ll move very slowly.

Thanks again for your help

Hey, it appears that you just added a comment called “-- Main loop” before the function starts
Did you mean to do something else?

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