Tween part around pivot point?

Hello!

I did a bit of looking around on this forum and I have only been able to find things using models and not specific parts. Not really sure where to begin.

Anyway, I am wondering how I would go about making this part pivot around a specific point?

Desired pivot point:

Crate lid:

Script:

local tweenService = game:GetService('TweenService')

local destinationCFrame = script.Parent.Lid.CFrame * CFrame.Angles(math.rad(180), 0, 0)

tweenService:Create(script.Parent:FindFirstChild('Lid'), TweenInfo.new(), {CFrame = destinationCFrame}):Play()

I’ve tried using a HingeConstraint and setting the model’s PrimaryPart to that pivot point part but still no success.

TIA for any help!

3 Likes

There is an example of rotating a door in this article go check it out, should be the same concept.

6 Likes

Short answer is that you can’t use TweenService to tween the lid like that because it only does linear interpolation between two CFrames and that’s just not what you’re after (the positions along the path you want form a circle arc, not a straight line).

3 Likes

Oh yeah good point, the article in understanding CFrame math operations requires that you need to change two CFrame values at once in order to rotate around a hinge.

	hinge.CFrame = hinge.CFrame * CFrame.Angles(0, math.rad(1)*dt*60, 0) -- rotate the hinge
	door.CFrame = hinge.CFrame * offset -- apply offset to rotated hinge

Luckily theres a trick I did in another post with a helmet which gets around this issue by creating an CFrame Instance value to change both the hinge CFrame and the CFrame of the Lid at the same time

Full Script
llocal TweenService = game:GetService("TweenService")

local Lid = script.Parent

local Info = TweenInfo.new(
	0.2,
	Enum.EasingStyle.Linear
)

local pivotHingeInitialCFrame = script.Parent.HingeAttachment.WorldCFrame

local offset = pivotHingeInitialCFrame:Inverse()*Lid.CFrame

local hingeCFrameValue = Instance.new("CFrameValue")
hingeCFrameValue.Value = pivotHingeInitialCFrame

hingeCFrameValue.Changed:Connect(function(newHingeCFrame)
	Lid.CFrame = newHingeCFrame*offset
end)

local function Close()
	local CloseGoal = {}
	CloseGoal.Value = pivotHingeInitialCFrame
	local Tween = TweenService:Create(hingeCFrameValue,Info,CloseGoal)
	Tween:Play()
	Tween.Completed:Wait()
end

local rotationAmount = math.rad(90)

local function Open()
	local OpenGoal = {}
	OpenGoal.Value =  pivotHingeInitialCFrame*CFrame.Angles(rotationAmount,0,0)
	local Tween = TweenService:Create(hingeCFrameValue,Info,OpenGoal)
	Tween:Play()
	Tween.Completed:Wait()
end

while true do
	Close()
	wait(1)
	Open()	
	wait(1)
end

Same concept as the article but this time uses an attachment instead of another part to represent the CFrame of the hinge:

Here’s the Lid as a model:

However, I believe there should be another simpler solution that generates the offset CFrame value using something like a rig editor which generates the joints and the hinge pivot, but yeah it’s up to you.

10 Likes

i don’t see the door example can you specify where it is?

vertical lids may sometimes refuse to be operated with HingeConstraint Servo actuator bc of their mass; also, you should keep in mind that any parts obstructing each other, such as hinges themselves, should be set to CanCollide = false; and last but not least, servo’s limits should be taken care of, bc sometimes the MeshPart comes inverted 180 degrees from the editor, and limits therefore must be inverted, too