I was scripting an automatic door for a group, and I wanted it to open and stay open until the player went outside of the sensor. I tried using the .TouchEnded event, but it was very unreliable and would make the doors “flinch” every time that I moved inside of the sensor. So, I created a script that would stay open for two seconds and close no matter what, but that was not what I was originally planning for.
Here is my script:
local TweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(
0.5,
Enum.EasingStyle.Linear,
Enum.EasingDirection.Out,
0,
false,
0
)
local door1 = game.Workspace.Door1
local door2 = game.Workspace.Door2
local tween1 = TweenService:Create(door1, tweenInfo, {Position = Vector3.new(21.394, 5.43, 68.865)})
local tween2 = TweenService:Create(door2, tweenInfo, {Position = Vector3.new(53.393, 5.43, 68.865)})
local tween3 = TweenService:Create(door1, tweenInfo, {Position = Vector3.new(32.332, 5.43, 68.865)})
local tween4 = TweenService:Create(door2, tweenInfo, {Position = Vector3.new(42.625, 5.43, 68.865)})
script.Parent.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild("Humanoid") then
tween1:Play()
tween2:Play()
wait(2)
tween3:Play()
tween4:Play()
end
end)
Is there a better workaround for what I originally intended instead of using either .TouchEnded or wait(x)?
To build on top of this, it would be a good idea to;
Add players to a table when they touch the ‘open door’ trigger (When they get in radius)
Remove them from the table when they walk away far enough (When they are for sure not going to walk in the door again)
Check when player characters are removed from Workspace, and remove them from the table
Whenever one of the three actions above occur, check if there are entries in the table. If there are, the door should open / be opened. If it’s empty, it’s safe to close the door.
That would be the best way to ensure the door can never be in someone’s way. It’s a little more complicated, but if you only keep track of one player (the most recent who touched the door) you will most likely still end up with a door that closes in front of players.
You could make a function that checks all touching parts and call this function when a touch started or ended.
local SensorPart = script.Parent
local IsOpen = false
local function Open()
--Open the door
end
local function Close()
--Close the door
end
local function CheckTouches()
local IsPlayerInside = false
for _,v in pairs(SensorPart:GetTouchingParts()) do
if v and v.Parent and game.Players:GetPlayerFromCharacter(v.Parent) then
IsPlayerInside = true
break
end
end
if not IsOpen == IsPlayerInside then
if IsPlayerInside then
Open()
IsOpen = true
else
Close()
IsOpen = false
end
end
end
SensorPart.Touched:Connect(CheckTouches)
SensorPart.TouchEnded:Connect(CheckTouches)