Putting an Object in Orbit

I am attempting to make an object be in Orbit. edit: In other words, I’d like to more or less create a centripetal force.
If you look at the provided photo, I am attempting to get the red Circle to move around in a wider circle, just as a planet is in orbit. Players won’t be able to touch it, so no need to worry about that.


I’ve moved objects left-right, but never in a circle. If anyone could give me any bit of help, that’d be awesome!


Probably the worst ever way to do it but it works:

Put this script inside an anchored part

while wait(.01) do
	script.Parent.CFrame = CFrame.new(
		(script.Parent.CFrame * 
			CFrame.new(0, 0, .1)
		(script.Parent.CFrame * 
			CFrame.new(.3, 0, -20)).p

It works and I’m thankful for that, but is there a way I could set how much time I want it to take and it’d complete a full circle in that time?

When I’m home I’ll write a better one up that has those options unless someone else has

1 Like

Hi! You can use the math functions sin() and cos() to make an orbit on a plane (with adjustabe time)

The CFrame’s X position would be:
math.sin(time() * speed) * radius
and the Z position would be:
math.cos(time() * speed) * radius)

If you move around the arguments, you can get circles on different planes. Getting circles between planes is a little more complex, so I’m unsure if i would be able to help with that.

Good luck!

P.S. I’m on mobile so please forgive the lack of depth!

Edit: This is not optimal, but will work if you don’t have many: (untested!)
local speed = 1;
local radius = 2;
Local baseCFrame = script.Parent.CFrame;
while true do
script.Parent.CFrame = baseCFrame + CFrame.new(math.sin(time() * speed) * radius), 0, math.cos(time() * speed) * radius));


Error Message: Workspace.Part.Script:5: bad argument #2 to ‘?’ (Vector3 expected, got CFrame)

You could use physics and constraints for this. I’m not entirely sure how, but it is possible, probably easily without scripts. Not sure if it’d be laggy, depends on size and amount of objects moving.

Here’s a script I just made that assumes “Body” is the object being orbited around and “Satellite” is the satellite.
If you want the rotation of the body to affect the orbit, replace CFrame.new(Body.Position) with Body.CFrame.

orbitPeriod = 2
orbitRadius = 10
orbitVerticalDisplacement = 0
for t = 0, math.huge do
	Satellite.Position = CFrame.new(Body.Position)*CFrame.Angles(0, t/orbitPeriod * math.pi/30, 0)*Vector3.new(orbitRadius, orbitVerticalDisplacement, 0)
	game['Run Service'].Heartbeat:wait()

My friend helped me come up with this with the help of you guys, thank you all!

local radius = 10
local center = Vector3.new()
local rad, cos, sin = math.rad, math.cos, math.sin
local totalTime = 50

for i = 1, math.huge do
script.Parent.CFrame = CFrame.new(center.X + radius*cos(rad(i%1440)), center.Y, center.Z + radius*sin(rad(i%1440)))
1 Like

wait() has a limited precision, I think it’s precise to one frame or something.
You should never use it for something where a massive difference will be made by it being one frame shorter or longer.
In your case, totalTime (which I assume is the period) can be increased or decreased significantly without affecting how long an orbit takes, because your wait period is only two frames.

Actually, I think small changes in totalTime does still affect how long an orbit takes, because as far as I can tell a two-and-a-half frame wait has a half chance of being two frames and a half chance of being three frames.
But you might as well go with a neater solution and have every step last one frame, with the period determining the angle change per frame.

I don’t know what this is being used for, but if it’s just moving in circles it’s more efficient to use a Motor6D


A lot of these examples are for circular motion, which a planet in orbit isn’t actually doing. When in orbit, a planet or any other celestial body will have an orbit that’s an ellipse. While the math that’s provided from the others does help with actually moving the planet through its orbit, just make sure that the orbit path is technically correct. :slight_smile:

1 Like

Well, the problem is, I have no clue how to get a somewhat oval? Since that’s how a lot of planets orbit.

An oval is just a stretched/squished circle in one of its two dimensions

Instead of having one radius, you just have two: one for each direction.

local radiusX = 10
local radiusZ = 20

Then you modify your call to be

script.Parent.CFrame = CFrame.new(center.X + radiusX*cos(rad(i%1440)), center.Y, center.Z + radiusZ*sin(rad(i%1440)))

Keep in mind that when you do this, the speed along the curve is not constant anymore. You’ll need some more complicated math for that if you want to have an ellipse and also moving it along the curve at constant speed.


Orbital.rbxl (14.1 KB)

Made a fun example of oval orbits :smiley:

Can even make earth orbit the sun too :smiley: Orbital.rbxl (14.3 KB)

@buildthomas I dont think speed should be constant on an oval orbit anyways.


Not entirely constant yeah, but I think actual planets move somewhere along a middle ground between your example and constant speed :sweat_smile:

@buildthomas & @PlaceRebuilder Thank you!! I’ll be trying this out later this afternoon.

i know im late but look up math.cos and math.sin, they basically make a wavy pattern, as in math.cos(tick()) would control the y vector while math.sin(tick()) would control the x vector

1 Like

You could try my module. It is a simple and easy to use free module that contains circular orbits, eccentric orbits and elliptical orbits currently!

Get it here now : Tomroblox54321’s Advanced Planetary Orbit Module!

1 Like