I think the code would be a little bit easier to understand if it weren’t such a pyramid!
It would also be easier to understand what’s going on if the script told you what it’s doing, so I’ve added a lot of print()s.
for i,v in pairs(game.Workspace.Doors:GetChildren()) do
-- EDIT: moved Can variable here, read the note at the bottom of the post
local Can = true
local Open = v.Open.Value
Open = false -- uhh, why do you do this? The actual value of v.Open.Value is ignored
print("Processing door", v)
v.Event.OnServerEvent:Connect(function(Player)
print("Player attempts to use door", Player, v)
local Mag = (v.Center.Position - Player.Character.HumanoidRootPart.Position).Magnitude
-- EDIT: made the function return if the player is too far, instead of doing something if the player is close.
if Mag > v.Range.Value then return end
print("Close enough")
-- EDIT: again, turned the if Can then ... into a if not Can then return end
-- This keeps the code nearer to the left margin.
if not Can then return end
print("Not currently being used, either")
--FAULTY PART STARTS
-- ??? This looks fine to me
if v.Name == "Locked" then
print("Door is locked")
if not Player:IsInGroup(v.GroupID.Value) then
print("Player can't use the door, not in group", v.GroupID.Value)
return
else
print("Player is allowed to use the locked door", v.GroupID.Value)
end
-- EDIT: added an end right here. The behavior changes.
-- This means that a door that is named "Locked" can only be opened by a member of the group.
-- A door that isn't named "Locked" can be opened by anyone.
else
print("Door is not locked")
end
--FAULTY PART ENDS
Can = false
if Open == false then
print("Opening door")
Open = true -- EDIT: moved this line up for clarity
-- NOTE: you can do a bit better by rotating the door with a tween, but otherwise there's nothing wrong with it
-- Due to inaccurate calculations, the door might also shift a little bit out of place after opening-closing a thousand times, this can be solved by remembering the position where the door should be when it's closed, then tweening to that to close the door, and to (closed position * some rotation) to open it. Again, nothing too bad about the code here right now
local finish = v.PrimaryPart.CFrame*CFrame.Angles(0,math.rad(88),0)
for i = 0,0.7,.1 do
local cfm = v.PrimaryPart.CFrame:lerp(finish,i)
v:SetPrimaryPartCFrame(cfm)
wait()
end
else
print("Closing door")
Open = false
local finish = v.PrimaryPart.CFrame*CFrame.Angles(0,-math.rad(88),0)
for i = 0,0.7,.1 do
local cfm = v.PrimaryPart.CFrame:lerp(finish,i)
v:SetPrimaryPartCFrame(cfm)
wait()
end
end
Can = true
print("Finished interacting with door")
end)
end
In addition, one issue (unrelated to your problem) which I noticed and solved in the code above: the Can variable is used as a debounce by all doors. Therefore, if one door is currently opening/closing, then no others can be used at the same time.
Simply move local Can = true just inside the for loop to make it local to each door.
After writing this post, I didn’t really find any reason why this door shouldn’t work, even with your original code.
You should have debugged your code by putting print()s all over the code and seeing what it prints and why.
I don’t think there’s anything wrong in the local script.