I am currently trying to make a door. I want to smoothly tween the door using Lerp. I can get it to tween but not the way I would like. I need it to rotate around the hinge but instead of rotating around the hinge it slides the door and rotates at the same time and the door ends up going through the door frame post. Here is a video of my problem
any idea how I can get lerp to just rotate around the pivot point? Here is my code so far, thanks
local startCFrame = workspace.Door.CFrame
local door = workspace.Door
local endCFrame = door.CFrame * CFrame.new(0, 0, door.Size.Z/2) *CFrame.Angles(0,
math.rad(90), 0) *CFrame.new(0, 0, -door.Size.Z/2)
local desiredDuration = 2
local durationReciprocal = 1/desiredDuration
local startTime = tick()
local steppedEvent
steppedEvent = game["Run Service"].Stepped:Connect(function()
local timeElapsed = tick() - startTime
local alpha = timeElapsed * durationReciprocal
local newCFrame = startCFrame:Lerp(endCFrame, alpha)
workspace.Door.CFrame = newCFrame
if alpha >= 1 then
steppedEvent:Disconnect()
workspace.Door.CFrame = endCFrame
end
end)
The easiest way to do that is by editing the CFrame.Angles component from endCFrame to create your new door’s CFrame every frame:
local door = workspace.Door
-- you'll see why I use numbers later on,
local startAngle = 0
local endAngle = math.rad(90)
startCFrame = door.CFrame
local sizeZ = CFrame.new(0, 0, door.Size.Z/2)
local duration = 2
local steppedEvent
local alpha = 0
steppedEvent = game:GetService("RunService").Stepped(function(gameTime, timeElapsed)
-- incrementing alpha by time passed / duration, the way I usually do it
alpha = math.min(alpha + timeElapsed/duration, 1)
-- also clamps at 1 so you don't have to worry about repositioning
-- lerping to the new angle
local newAngle = (endAngle - startAngle) * alpha + startAngle
-- from the creation of your endCFrame
local newCFrame = startCFrame
* sizeZ -- CFrame.new(0, 0, door.Size.Z/2)
* CFrame.Angles(0, newAngle, 0)
* sizeZ:Inverse() -- CFrame.new(0, 0, -door.Size.Z/2)
door.CFrame = newCFrame
if alpha >= 1 then
steppedEvent:Disconnect()
end
end)
In theory, sizeZ and sizeZ:Inverse() should work in the newCFrame formula, but you can just use the commented ones if they do something weird.
If you want to make your tween even smoother, you can use TweenService:GetValue to get an alpha value in the inputted easing style and easing direction.
I seem to have a problem it only works if the script runs right when the game starts, if I disable and enabled it again it jumps to the next position without tweening.
If you’re running this on the server, RunService wouldn’t have a RenderStepped event, you would have to use Stepped like your code or Heartbeat.
I made a local alpha every frame instead of assigning to global alpha, which made the door stay at one angle the entire time. You can just take out the local in local alpha = math.min(alpha + elapsedTime/duration, 1)
I just tested this in my own place, it should work now.