Edit: in my pursuit for the best doors, I’ve found that there are much betters ways to do this. Is there a case where you might want to do it this way? Maybe, but probably not for a door. For now I would recommend tweening a hinge with a door welded to it on a LocalScript. Good luck! I’ll probably take this down or completely overhaul it someday, and probably just distribute a modulescript that gets the job. For now, here’s the original tutorial:
All the answers I’ve found to the question “tweening a door around a hinge” have been unsatisfactory. They either use a lerp, or tween the hinge itself which is welded to the unanchored door, or some other method, all of which haven’t been ideal solutions because the tweening (or use of TweenService2 or BoatTween) aspect has been crucial – and well, I don’t want unanchored parts. Here are the steps I went on to get this final result:
- We gotta know what to do. I want to move a door across its hinge with all the TweenInfo goodness of Time and EasingStyle properties. I thought using CFrames was the way to go, and tried out this example for myself. Looks good!
- Let’s just change it up a bit so I can use TweenService. I should only need to keep track of the doors open and closed positioning… right? The following code produces the following result:
local door = script.Parent
local hinge = door.Parent.hinge
local tweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new()
local offset = hinge.CFrame:Inverse() * door.CFrame
local doorOpen = tweenService:Create(door, tweenInfo, {CFrame = hinge.CFrame * CFrame.Angles(0, math.rad(90), 0) * offset})
local doorClose = tweenService:Create(door, tweenInfo, {CFrame = hinge.CFrame * CFrame.Angles(0, 0, 0) * offset})
wait(3)
doorOpen:Play()
wait(3)
doorClose:Play()
- The door is opening and closing, but definitely not around the hinge. The door needs to rotate on an axis about an angle, and not get translated and reoriented the shortest possible way to the destination. Here’s where I combine TweenService and the Heartbeat methods.
local door = script.Parent
local hinge = door.Parent.hinge
local tweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new()
local offset = hinge.CFrame:Inverse() * door.CFrame
local doorOpen = tweenService:Create(door.Angle, tweenInfo, {Value = 90})
local doorClose = tweenService:Create(door.Angle, tweenInfo, {Value = 0})
game:GetService("RunService").Heartbeat:Connect(function(dt)
door.CFrame = hinge.CFrame * CFrame.Angles(0, math.rad(door.Angle.Value), 0) * offset
end)
wait(3)
doorOpen:Play()
wait(3)
doorClose:Play()
Look at that! It’s exactly like we want it, and it only took an extra three lines of code and an “Angle” NumberValue
!
Obviously in this situation I didn’t want the hinge itself to rotate, but if you’ve gotten here I’m sure you can do it. Additionally, I didn’t make use of custom TweenInfo, opting for the defaults – but the option to give it a whole bunch of properties is now here with this solution to Tweening a Door Around a Hinge. Hope this is useful for some people. Any feedback would be appreciated, too!