I am using TweenService to rotate a part in a certain direction, but I am having trouble figuring out how to have this rotation occur from the edge of a part (or any portion of the part that is not the center of it), with a motion similar to that of opening a trap door, or opening a door.
Is this possible to do with TweenService? If not, what alternatives are there?
I believe I am wrong, although, I may not be wrong, but I believe pivots are not for position just for a better fix for rotation of a model. I suggest you look into it to make sure I am not wrong.
At this point, I would make a “custom tween”, which is actually somewhat simple, you can even keep using easing styles using TweenService:GetValue()
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local function Tween(TweenFunction : (alpha : number) -> nil, Duration : number, EasingStyle : Enum.EasingStyle?, EasingDirection : Enum.EasingDirection)
EasingStyle = EasingStyle or Enum.EasingStyle.Linear
EasingDirection = EasingDirection or Enum.EasingDirection.Out
local StartTime = os.clock()
while true do
local alpha = math.min((os.clock() - StartTime)/Duration,1) -- Value that goes from 0 to 1 (0% to 100%). It also cannot go above 1 because of the math.min(Value,1)
alpha = TweenService:GetValue(alpha, EasingStyle, EasingDirection)
TweenFunction(alpha)
if alpha == 1 then break end
RunService.RenderStepped:Wait()
end
end
--
local Part = game.Workspace.Part
local Origin = Part.CFrame
local StartPivot = Origin -- No pivot, other than the initial rotation of the part
local EndPivot = Origin * CFrame.Angles(0,math.pi/2,0) -- 90 degrees
local Offset = CFrame.new(0,0,4) -- Part is 4 studs from the pivot. Set this to Size/2, to make it rotate on the edge of the part
local TweenFunction = function(alpha : number)
Part.CFrame = StartPivot:Lerp(EndPivot,alpha) * Offset
end
Tween(TweenFunction, 5, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)
There are different ways to make a custom tween thing. If you want your part to have a repeating motion, you can make that directly instead of looping the tween, or you could add to this by adding a looping boolean, etc
TweenService can definitely be used to achieve your desired result. All you need to do is make sure the object is a model (even if it’s just one singular part), and create another (smaller) part that will act as the center (in this case put it on the edge).
Set the model’s PrimaryPart to the smaller part
Weld the descendants of the model to the Primary Part
Use TweenService on the PrimaryPart, the rest of the model will follow it’s movement.
Make sure the PrimaryPart is Anchored, and everything else is NOT anchored
This code can be used to weld all descendants of a model to it’s primary part.
function module:WeldDescendantsToPart(part1, part2)
part2 = part2 or part1 -- if no part2 is provided, weld everything to part1
for i, part in pairs(part1:GetDescendants()) do
if part:IsA("BasePart") and part ~= part2 then
part.Anchored = false
local weld = Instance.new("WeldConstraint")
weld.Part0 = part2
weld.Part1 = part
weld.Parent = part
end
end
end
WeldDescendantsToPart(model, model.PrimaryPart) --example call
--Tween the PrimaryPart
This solution ended up working out, but now I have a different issue revolving around using :PivotTo() and the tween. I’ll look into how I can fix that though; I appreciate all the responses here!