Here is a basic Tween Animation that you could modify to your liking:
local tweenInfo = TweenInfo.new(
1, -- Time
Enum.EasingStyle.Linear, -- EasingStyle
Enum.EasingDirection.Out, -- EasingDirection
0, -- RepeatCount (when less than zero the tween will loop indefinitely)
false, -- Reverses (tween will reverse once reaching it's goal)
0 -- DelayTime
)
local tween = TweenService:Create(script.Parent.Door, tweenInfo, {CFrame = "final destination CFrame"})
tween:Play()
local TweenService = game:GetService('TweenService') -- Get the TweenService
local tweenInfo = TweenInfo.new(5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut) -- Create a TweenInfo for your tween
local PartToTween = workspace.Part; -- Find a part that you want to tween
local CurrentCFrame = PartToTween.CFrame; -- The original CFrame (The Closed Position)
local NewCFrame = PartToTween.CFrame *CFrame.new(-5, 0, 0) -- The Open CFrame
local NewTween = TweenService:Create(PartToTween, tweenInfo, {CFrame = NewCFrame}) -- Create a new Tween
NewTween:Play() -- Runs the CFrame
You will need to run a tween when you want to Open the door and Close the door unless you set Reverse to true in the TweenInfo.
A CFrame represents both Position and Orientation. Setting the CFrame in the third argument, the “goal” table, will make it tween until it reaches that Position and Orientation. So it’s not “how far it goes” so much as “where it goes”. It’ll always go to the same position, regardless of where it started.
Unfortunately that’s a limitation with the reverse aspect of tweening currently unless I’m mistaken. It’s simple enough to have two separate tweens for the Opening and Closing, and you can use the .Completed event to yield until it has finished tweening:
local openTween = TweenService:Create(Part, tweenInfo, {CFrame = OpenCFrame})
openTween:Play()
openTween.Completed:Wait() -- Yields the code until the tween is completed
local closeTween = TweenService:Create(Part, tweenInfo, {CFrame = CloseCFrame})
closeTween:Play()
closeTween.Completed:Wait() -- " .. "