Why won't this door script work?

Hello! I have a simple door script. I am trying to make a specific type of doors group locked, but it doesn’t seem to work. The door opens anyway, even if the player isn’t in the group.

Here is my script.

local Can = true

for i,v in pairs(game.Workspace.Doors:GetChildren()) do
	local Open = v.Open.Value
	Open  = false
	v.Event.OnServerEvent:Connect(function(Player)
		local Mag = (v.Center.Position-Player.Character.HumanoidRootPart.Position).Magnitude
		if Mag <= v.Range.Value then
--FAULTY PART STARTS
			if v.Name == "Locked" then
				if not Player:IsInGroup(v.GroupID.Value) then return end
--FAULTY PART ENDS
					if Can then
						Can = false
						if Open == false then
							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
							Open = true
						else
							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
					end
			end
		end
	end)
end

This is NOT the only script I have for this door system, do not worry about that.
If I write anything other than “then return end” (e.g. Player.Character:Destroy()), it works. There is nothing in the output.

Please help. I am genuinely clueless.

1 Like

Try doing:

if Player:IsInGroup(v.GroupID.Value) == nil then return end

Thats the same as doing

if not Player:IsInGroup(v.GroupID.Value) then return end
if Player:IsInGroup(v.GroupID.Value) == nil then return end

and

if not player:IsInGroup(v.GroupID.Value) then return end

Are the same. In both cases you check if the player isnt in the group and return it.

What is the other script[s] ? [relevant to this one], I see youre calling an event there, please show us the script where you fire the event.

Yeah sorry, first post.
I’ll explain the system more.
In workspace, I have a folder named Doors.
image
Inside a door are these (other than the door model itself)
image

In SSS, I have 2 scripts, one is the one I posted about and the other is basically the same without checking if the Player is in a group.

In RS I have “OpenDoor” event.

In PlayerGUI, I have a LocalScript.

local inputservice = game:GetService("UserInputService")

inputservice.InputBegan:connect(function(i,g)
    if i.UserInputType == Enum.UserInputType.Keyboard then
        if i.KeyCode == Enum.KeyCode.E then
            local closestDoor, closestRange = nil, nil
            for _,Door in pairs(workspace.Doors:GetChildren()) do
                if Door:FindFirstChild("Event") ~= nil then
                    local Mag = (Door.Center.Position-game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude
                    if Mag <= Door.Range.Value then
                        if closestRange == nil or closestRange > Mag then
                            closestDoor = Door
                            closestRange = Mag
                        end
                    end
                end
            end
            if closestDoor == nil then return end
            closestDoor.Event:FireServer()
        end
    end
end)

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.

2 Likes

Thanks for your contribution, tõesti tänud.

There’s currently no issue with the local Open part of the script, If I remember correctly that’s why I added “local Open = v.Open.Value”

I found the solution. I had made a duplicate of the script, which meant that whatever I do to the first script, the other runs with the original code (if you understand)

Thanks for making the script clearer, it did help a lot.

1 Like