Make part rotate on a fixed point (edge of part)

I’m trying to create like a door swivel animation, but can’t seem to find anything on how to make a part swivel on a fixed point. Currently I’ve got it so the door rotates on the centre axis, and it constantly spins, instead of stopping :grimacing:

local function RenderStepped()
	Door = nil
	
	local Character = Player.Character
	if Character then
		local HumanoidRootPart = Character:FindFirstChild('HumanoidRootPart')
		if not HumanoidRootPart then return end

		for _, v in pairs(AllDoors) do
			local Distance = (v.CFrame.Position - HumanoidRootPart.CFrame.Position).magnitude
			if not Door or Distance <= Door.Distance then
				Door = {
					Current = v, 
					Distance = Distance
				}
			end
		end
		
		if not Door then return end
		
		local Distance = Door.Distance
		
		local Hinge = Door.Current.Parent:FindFirstChild('Hinge')
		if not Hinge then return end
						
		if Distance <= ReachableDistance then
			local DoorOpen = TweenService:Create(Door.Current, TweenInfo.new(), {CFrame = Door.Current.CFrame * CFrame.Angles(0, math.rad(45), 0)}):Play()
		else
			print('Close')
		end
	end
end

If I’ve made this more convoluted than it needs to be then please let me know :grimacing:

How I lay the models out


Basically, Buildings are the exteriors, and Rooms are the interiors. They have a Door, which is the part that swings open, Teleporter which when touched teleports the player into the respective spot, and then Hinge, which is the axis the door should swing on.

I would put a part called hinge inside the door and add WeldConstraint between the door and the hinge
image

And here is my script:

local TweenService = game:GetService("TweenService")

local hinge = script.Parent.Hinge

local openGoal = {}
openGoal.CFrame = CFrame.new(hinge.Position) * CFrame.Angles(0, math.rad(90), 0)
local closeGoal = {}
closeGoal.CFrame = CFrame.new(hinge.Position) * CFrame.Angles(0, math.rad(0), 0)

local tweenInfo = TweenInfo.new(2)
local openTween = TweenService:Create(hinge, tweenInfo, openGoal)
local closeTween = TweenService:Create(hinge, tweenInfo, closeGoal)

local closed = true

script.Parent.Part.ClickDetector.MouseClick:Connect(function()
	if closed then
		openTween:Play()
		closed = false
	else
		closeTween:Play()
		closed = true
	end
end)

now the door doesn’t rotate on the center axis

1 Like

Not sure if I’m doing something wrong, but it’s not working

The open print does print

local function NearestDoorChanged(door)
	local CurrentDoor
	if not CurrentDoor then
		CurrentDoor = door
	end
	
	if CurrentDoor then
print('Open')
		local openGoal = {}
		openGoal.CFrame = CFrame.new(CurrentDoor.Hinge.Position) * CFrame.Angles(0, math.rad(90), 0)
	
		local tweenInfo = TweenInfo.new(2)
		local openTween = TweenService:Create(CurrentDoor.Hinge, tweenInfo, openGoal)
		
		openTween:Play()
	else
		print('Door has not been found, close')
	end
	
	CurrentDoor = door
end

Make sure the hinge is anchored and the door itself unanchored (and the hinge connected to the door with weldconstraint)

Also try changing the math.rad in cframe angles to negative 90 and change the math.rad parameter place between the braces because the rotation might depend on where the door is placed

This seems to work, HOWEVER

if door then
		local Goal = {}
		Goal.CFrame = CFrame.new(CurrentDoor.Hinge.Position) * CFrame.Angles(0, -math.rad(120), 0)
	
		local Tween = TweenService:Create(CurrentDoor.Hinge, TweenInfo.new(0.5, Enum.EasingStyle.Bounce), Goal)
		
		Tween:Play()
	else
		local Goal = {}
		Goal.CFrame = CFrame.new(CurrentDoor.Hinge.Position) * CFrame.Angles(0, 0, 0)
	
		local Tween = TweenService:Create(CurrentDoor.Hinge, TweenInfo.new(0.5), Goal)
		
		Tween:Play()
	end

If the door is rotated on a different angle, then it doesn’t work. I need it to rotate relative to the doors position :confused:
ezgif.com-video-to-gif

Hold on, I am in school at the moment. When I’m home I will look into it.

I made a new script that rotates the hinge relative to it’s position

local TweenService = game:GetService("TweenService")

local hinge = script.Parent.Hinge

local openGoal = {}
openGoal.CFrame = hinge.CFrame:ToWorldSpace(CFrame.Angles(0, math.rad(90), 0))
local closeGoal = {}
closeGoal.CFrame = hinge.CFrame:ToWorldSpace(CFrame.Angles(0, math.rad(0), 0))

local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Bounce)
local openTween = TweenService:Create(hinge, tweenInfo, openGoal)
local closeTween = TweenService:Create(hinge, tweenInfo, closeGoal)

local closed = true

script.Parent.Part.ClickDetector.MouseClick:Connect(function()
	if closed then
		openTween:Play()
		closed = false
	else
		closeTween:Play()
		closed = true
	end
end)

So in your case it would be

if door then
		local Goal = {}
		Goal.CFrame = CurrentDoor.Hinge.CFrame:ToWorldSpace(CFrame.Angles(0, -math.rad(120), 0))
	
		local Tween = TweenService:Create(CurrentDoor.Hinge, TweenInfo.new(0.5, Enum.EasingStyle.Bounce), Goal)
		
		Tween:Play()
	else
		local Goal = {}
		Goal.CFrame = CurrentDoor.Hinge.CFrame:ToWorldSpace(CFrame.Angles(0, math.rad(0), 0))
	
		local Tween = TweenService:Create(CurrentDoor.Hinge, TweenInfo.new(0.5), Goal)
		
		Tween:Play()
	end

I hope this helps

Door doesn’t wanna shut when door == nil

if door then
		local Goal = {}
		Goal.CFrame = CurrentDoor.Hinge.CFrame:ToWorldSpace(CFrame.Angles(0, -math.rad(120), 0))
	
		local Tween = TweenService:Create(CurrentDoor.Hinge, TweenInfo.new(0.5, Enum.EasingStyle.Bounce), Goal)
		
		Tween:Play()
	else
		print('Close')
		local Goal = {}
		Goal.CFrame = CurrentDoor.Hinge.CFrame:ToWorldSpace(CFrame.Angles(0, math.rad(0), 0))
	
		local Tween = TweenService:Create(CurrentDoor.Hinge, TweenInfo.new(0.5), Goal)
		
		Tween:Play()
	end

print(‘Close’) does print (when door == nil) however the door just stays open. And since door stays open, when you go back, it rotates the door more and more, until it goes back to the beginning (3 times, as 3*120 = 360)
ezgif.com-video-to-gif (1)

Try changing your script to

if door then
		local Goal = {}
		Goal.CFrame = CurrentDoor.Hinge.CFrame:ToWorldSpace(CFrame.Angles(0, -math.rad(120), 0))
	
		local Tween = TweenService:Create(CurrentDoor.Hinge, TweenInfo.new(0.5, Enum.EasingStyle.Bounce), Goal)
		
		Tween:Play()
	else
		print('Close')
		local Goal = {}
		Goal.CFrame = CurrentDoor.Hinge.CFrame:ToWorldSpace(CFrame.Angles(0, math.rad(120), 0))
	
		local Tween = TweenService:Create(CurrentDoor.Hinge, TweenInfo.new(0.5), Goal)
		
		Tween:Play()
	end