How would i make a door that opens and closes with proximity prompt

So here’s the script i made but sadly it only opens the doors and after spamming the proximity prompt it closes the door. i want it to open everytime i use proximity prompt and make it close

local test = true
local doormodel = script.Parent.Parent.Parent

local tweenservice = game:GetService("TweenService")
local tweeninfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)

local doorTween = tweenservice:Create(doormodel.Part, tweeninfo, {CFrame = doormodel.OtherPart.CFrame})
local doorTween2 = tweenservice:Create(doormodel.Part, tweeninfo, {CFrame = doormodel.BACK.CFrame})


script.Parent.Triggered:Connect(function()
	script.Parent.Parent.door_open:Play()
	script.Parent.Parent.Parent.Part.Keyhole.Transparency = 1
	script.Parent.Parent.Parent.Part.Keyhole.CanCollide = false
	doorTween:Play()
	test = true
	script.Parent.Triggered:Connect(function()
		script.Parent.Parent.door_open:Play()
		doorTween2:Play()
		test = false
	end)
end)

you have got a memory leak here
let me attempt to explain
lets say we have a list of functions that are connected to the Triggered Event

{ }

after you connect a function to it

{
	function()
		script.Parent.Parent.door_open:Play()
		script.Parent.Parent.Parent.Part.Keyhole.Transparency = 1
		script.Parent.Parent.Parent.Part.Keyhole.CanCollide = false
		doorTween:Play()
		test = true
		script.Parent.Triggered:Connect(function()
			script.Parent.Parent.door_open:Play()
			doorTween2:Play()
			test = false
		end)
	end
}

list of connected functions looks like this ^
after you trigger the proximity prompt roblox goes through this list and calls every function

for i, func in pairs(ConnectedFunctions) do
	func()
end

but hey after you trigger proximity prompt and it calls all its connected functions and thus it connects another function that is inside the first function

script.Parent.Triggered:Connect(function()
	script.Parent.Parent.door_open:Play()
	doorTween2:Play()
	test = false
end)

and now list of connected functions looks like this

{
	function()
		script.Parent.Parent.door_open:Play()
		script.Parent.Parent.Parent.Part.Keyhole.Transparency = 1
		script.Parent.Parent.Parent.Part.Keyhole.CanCollide = false
		doorTween:Play()
		test = true
		script.Parent.Triggered:Connect(function()
			script.Parent.Parent.door_open:Play()
			doorTween2:Play()
			test = false
		end)
	end,
	function()
		script.Parent.Parent.door_open:Play()
		doorTween2:Play()
		test = false
	end
}

so now when you trigger proximity prompt for the second time 2 funcions are being called
but as the first function has not changed it connects yet another function to the list

script.Parent.Triggered:Connect(function()
	script.Parent.Parent.door_open:Play()
	doorTween2:Play()
	test = false
end)

and now list of connected functions looks like this

{
	function()
		script.Parent.Parent.door_open:Play()
		script.Parent.Parent.Parent.Part.Keyhole.Transparency = 1
		script.Parent.Parent.Parent.Part.Keyhole.CanCollide = false
		doorTween:Play()
		test = true
		script.Parent.Triggered:Connect(function()
			script.Parent.Parent.door_open:Play()
			doorTween2:Play()
			test = false
		end)
	end,
	function()
		script.Parent.Parent.door_open:Play()
		doorTween2:Play()
		test = false
	end,
	function()
		script.Parent.Parent.door_open:Play()
		doorTween2:Play()
		test = false
	end
}

as you can see every time you trigger that proximity prompt one unnecessary function is being added to the list of connected functions which takes up memory and is called multiple times

hope all above makes sense, now lets see how we could improve this code

-- i prefer to define services first its up to you
local tweenservice = game:GetService("TweenService")

local test = false -- not sure what is this here for

-- make sure to put repetitive patterns in a variable DRY principle (google)
-- i think making your variables start with capital initial makes it better to read
local ProxPrompt = script.Parent
local DoorModel = ProxPrompt .Parent.Parent
local KeyHole = doormodel.Part.Keyhole.Transparency

local TweenInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)

-- lets rename variables to make them more intuitive
local DoorOpen = tweenservice:Create(doormodel.Part, tweeninfo, {CFrame = doormodel.OtherPart.CFrame})
local DoorClose = tweenservice:Create(doormodel.Part, tweeninfo, {CFrame = doormodel.BACK.CFrame})

ProxPrompt.Triggered:Connect(function()
	test = not test -- lets use this test variable to represent whether the door is open or closed
	-- rename this test variable to IsOpen to give it a clearer definition
	if not test then -- if not opened then open
		doormodel.door_open:Play() -- i suppose this is sound effect
		Keyhole.Transparency = 1
		Keyhole.CanCollide = false
		DoorOpen:Play()
	else -- else close the door
		doormodel.door_close:Play() -- if there is one
		Keyhole.Transparency = 0
		Keyhole.CanCollide = true
		DoorClose:Play()
	end
end)
1 Like

After a few fixes it started working. Thanks!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.