My current game in development requires the use of 'laser distributors' and 'laser receptacles', additionally paired with several more custom-made items.
My current focus is on the distributor, which requires for the 'nozzle' or 'cannon' (/'launcher') brick to revolve in an orbit around the distributor's turret brick, always sticking inside-of the hull of the the brick in question.
The nozzle/cannon brick is required to make 90-degree rotations, always having one end of the brick (which is a cylinder) inside the hull; that doesn't mean that it can't move, just that it needs to appear-to-be in the hull at all times.
My current script, which has served me very well in the making of sliding-doors and hidden-panels, derived from the Roblox Wiki Article concerning Part Sliding is seen as below:
local Part = cannon -- this is the Part we will move
local newPos = Part.Position + Vector3.new(-2,0,2) -- the position the Part will go to
local Time = 5 -- the time that the script will take to move the part
local Increment = 0.05 -- the Part will move 0.05 studs each time it moves: smooth movements!
local Debounce = false
local Diff = newPos - Part.Position -- the difference between the two positions
local Mag = Diff.magnitude -- the distance between the two parts
local Direction = CFrame.new(Part.Position, newPos).lookVector
function MovePart() -- function to move the Part
if Debounce then return end -- end the function if debounce is true
Debounce = true -- make Debounce true so the function can't run
for n = 0, Mag, Increment do
Part.CFrame = Part.CFrame + (Direction * Increment)
wait( (Time/Mag) * Increment )
end
Debounce = false
end
script.Parent.ClickDetector.MouseClick:connect(MovePart)
I have tried to modify it to suit my need of an additional 'rotationAxis' argument, but that has met a brick-wall. Figuratively, of course...
local Part = cannon -- this is the Part we will move
local newPos = Part.Position + Vector3.new(-2,0,2) -- the position the Part will go to
local Time = 5 -- the time that the script will take to move the part
local Increment = 0.05 -- the Part will move 0.05 studs each time it moves: smooth movements!
local Debounce = false
local Diff = newPos - Part.Position -- the difference between the two positions
local Mag = Diff.magnitude -- the distance between the two parts
local Direction = CFrame.new(Part.Position, newPos).lookVector
local RotationAngle = Part.CFrame * CFrame.Angles(-45, 0, 45)
local RotationAxis = RotationAngle * Direction
function MovePart() -- function to move the Part
if Debounce then return end -- end the function if debounce is true
Debounce = true -- make Debounce true so the function can't run
for n = 0, Mag, Increment do
Part.CFrame = Part.CFrame + ( (Direction * Increment) * RotationAxis * Mag)
wait( (Time/Mag) * Increment )
end
Debounce = false
end
script.Parent.ClickDetector.MouseClick:connect(MovePart)
And bearing in mind that the Roblox Wiki's document on this is really really hard to understand, I can't fit my needs properly - hence why I came here.
To recap, the subject of assistance: Rotation Axis and Orbits: How do I create such thing?
If you have a viable solution, that is appreciated. Smiley face.
After-Note: It seems like I have solved the problem Myself. Albeit a bit 'laggy' and 'un-optimised', it serves well. You'll see my answer to the post.

3 comments
Great answer! Sorry I couldn't get to you - a lot of stuff happening and me forgetting that this site exists... Anyway, I have a few questions: How would I integrate the Heartbeat Service into the lerp'ing? I already have a basic idea, " Part.CFrame = this.CFrame:lerp( (this.CFrame * fromEulerAngles(0, 90, 0) ), timePassed / animationTime)
game:GetService("RunService").Heartbeat:connect(function(waiting) return end) --Instantly ends to take up one frame... "
Looks like you've got the right idea. In the Heartbeat:connect line, instead of "return" you should have your code from your first comment. You'll need to increase 'timePassed' by 'waiting'.