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.