How to keep my door from rotating out of position?

So I created a button prompted door swinging script which seems to work fine and dandy on the surface, but I noticed if I spam the the toggle button, the door will continue to tween out of position rather than opening and closing normally. How do I fix this? Here’s the local script:

local Player = game.Players.LocalPlayer
local PlayerGui = Player.PlayerGui
local UIS = game:GetService("UserInputService")
local DoorOpener = game:GetService("ReplicatedStorage").DoorOpener

UIS.InputBegan:Connect(function(Input,Istyping)
	if Istyping then
		return

	elseif Input.KeyCode == Enum.KeyCode.E then
		
		DoorOpener:FireServer()
	end
end)

local Insight = false
while wait() do
	if Insight == false then
		Insight = true
		local ButtonClone = script.Parent:Clone()
		ButtonClone.Parent = Player.PlayerGui
		ButtonClone.Adornee = workspace.Door
		script.Parent:Destroy()
		ButtonClone.TextLabel.Visible = true
	end
end

if Insight then
	if workspace.CurrentCamera:FindFirstChild("Button") then
		workspace.CurrentCamera.Button:remove()
	end
end

Here’s the server script:

local Tween = game:GetService("TweenService")
local Door = workspace.Door
local DoorHinge = Door.PrimaryPart
local DoorOpener = game:GetService("ReplicatedStorage").DoorOpener
local Info = TweenInfo.new()
local DoorSound = Door.DoorOpenSound

local opened = false

DoorOpener.OnServerEvent:Connect(function()
	local degree = 90
	if opened then
		degree = -90
		
		opened = false
	else
		opened = true
	end
	local TweenCreate = Tween:Create(DoorHinge,Info,{CFrame = DoorHinge.CFrame * CFrame.Angles(0,math.rad(degree),0)})
	wait(0.5)
	TweenCreate:Play()
	DoorSound:Play()
end)

Add a debounce variable called ‘isTweeningDoor’ to stop the door from being interrupted while moving:


local isTweeningDoor = false

DoorOpener.OnServerEvent:Connect(function()
	if isTweeningDoor then return end --exit out of the function if we're tweening the door already
	isTweeningDoor = true

	local degree = 90
	if opened then
		degree = -90
		opened = false
	else
		opened = true
	end
	local tween = Tween:Create(DoorHinge,Info,{CFrame = DoorHinge.CFrame * CFrame.Angles(0,math.rad(degree),0)})
	tween:Play()
	tween.Completed:Wait()
	DoorSound:Play()

	isTweeningDoor = false
end)

Now the door is unable to close

local TweenCreate = Tween:Create(DoorHinge,Info,{CFrame = DoorHinge.CFrame * CFrame.Angles(0,math.rad(degree),0)})

Your door will always tween relative to where it is at the moment it is clicked, and it can be clicked at any time.
To fix this, either stop using degree and instead have variables for where it should end up when open/closed:

-- ...
local opened = false
local cframeClosed = DoorHinge.CFrame
local cframeOpen = DoorHinge.CFrame * CFrame.Angles(0,math.rad(90),0)

DoorOpener.OnServerEvent:Connect(function()
	local target = cframeOpen
	if opened then
		target = cframeClosed
		
		opened = false
	else
		opened = true
	end
	local TweenCreate = Tween:Create(DoorHinge,Info,{CFrame = target})
	wait(0.5)
-- ...

Or prevent the door from being triggered when it is currently tweening, as pointed out by royaltoe.