Door keeps open until player leaves detector, but its unstable


I tried to yield if one of open tween completes, the door closes, but it doesn’t work. How I would do that?

Anyway, here is the code:

local TS = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(.3,Enum.EasingStyle.Linear,Enum.EasingDirection.In,0,false,0)

local model = script.Parent
local door = model.Door
local inDetector = model.InsideDetector
local outDetector = model.OutsideDetector
local pivot = door.Pivot

local inOpenGoal = {CFrame = pivot.CFrame * CFrame.Angles(0,0,math.rad(-90))}
local outOpenGoal = {CFrame = pivot.CFrame * CFrame.Angles(0,0,math.rad(90))}
local closeGoal = {CFrame = pivot.CFrame}

local touchedPlayer = {}

local isOpen = false

local db = false

local inOpenTween = TS:Create(pivot,tweenInfo,inOpenGoal)
local outOpenTween = TS:Create(pivot,tweenInfo,outOpenGoal)
local closeTween = TS:Create(pivot,tweenInfo,closeGoal)

local function inOpen()
	inOpenTween:Play()
end

local function outOpen()
	outOpenTween:Play()
end

local function close()
	if #touchedPlayer < 1 then
		closeTween:Play()
	end
end

outDetector.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		if not table.find(touchedPlayer,player) then
			table.insert(touchedPlayer,player)
		end
		if not isOpen then
			inOpen()
			isOpen = true
		end
	end
end)

inDetector.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		if not table.find(touchedPlayer,player) then
			table.insert(touchedPlayer,player)
		end
		if not isOpen then
			outOpen()
			isOpen = true
		end
	end
end)
inDetector.TouchEnded:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		if table.find(touchedPlayer,player) then
			table.remove(touchedPlayer,table.find(touchedPlayer,player))
		end
		if isOpen == true then
			close()
			isOpen = false
		end
	end
end)

outDetector.TouchEnded:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		if table.find(touchedPlayer,player) then
			table.remove(touchedPlayer,table.find(touchedPlayer,player))
		end
		if isOpen == true then
			close()
			isOpen = false
		end
	end
end)

Since the player has many body parts going Touching and Touchendeding on the detector it will go crazy if you aren’t tracking everything. For just the inDetector, I made your script count each touch event from each player, it should add up and count down as a player walks through it.

local TS = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(.3,Enum.EasingStyle.Linear,Enum.EasingDirection.In,0,false,0)

local model = script.Parent
local door = model.Door
local inDetector = model.InsideDetector
local pivot = door.Pivot

local inOpenGoal = {CFrame = pivot.CFrame * CFrame.Angles(0,0,math.rad(-90))}
local outOpenGoal = {CFrame = pivot.CFrame * CFrame.Angles(0,0,math.rad(90))}
local closeGoal = {CFrame = pivot.CFrame}

local touchedPlayer: {[Player]: number} = {}

local isOpen = false

local db = false

local inOpenTween = TS:Create(pivot,tweenInfo,inOpenGoal)
local outOpenTween = TS:Create(pivot,tweenInfo,outOpenGoal)
local closeTween = TS:Create(pivot,tweenInfo,closeGoal)

local function inOpen()
	inOpenTween:Play()
end

local function outOpen()
	outOpenTween:Play()
end

local function close()
	if #touchedPlayer < 1 then
		closeTween:Play()
	end
end

inDetector.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		-- counting how many touches per player
		if touchedPlayer[player] == nil then
			touchedPlayer[player] = 1
		else
			touchedPlayer[player] += 1
		end
		
		if not isOpen then
			inOpen()
			isOpen = true
		end
	end
end)

inDetector.TouchEnded:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		-- removing a touch per player
		touchedPlayer[player] -= 1
		if touchedPlayer[player] <= 0 then
			touchedPlayer[player] = nil
		end
		if isOpen == true then
			close()
			isOpen = false
		end
	end
end)