CollectionService doors problem

How I can make each one of the doors working individually and not being affected by others? This is my first time using CollectionService by the way.
I’ve tagged all of the doors properly and tried many solutions and searching for help constantly but no hope. This is my last resort.

Any helps will be appreciated.

The problem:
https://gyazo.com/bea79d87addcdcaecb8808f11c9a9749

Server Script:

-- [Variables] --

local Table1 = {}
local Table2 = {}

-- [Services] --

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local CollectionService = game:GetService("CollectionService")

-- [Setting up] --

local TaggedDoors = CollectionService:GetTagged("OpenableDoor")

local RemoteEvent = ReplicatedStorage:WaitForChild("Door Open")

local TweenInfo = TweenInfo.new(.85, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)

-- [Events] --

RemoteEvent.OnServerEvent:Connect(function(Player, Value)
    if Value == "Signal" then
        for _, taggeddoor in ipairs(TaggedDoors) do    

            if not Debounce then Debounce = Table1[taggeddoor] end
            if not InAction then InAction = Table2[taggeddoor] end

            if not Properties then Properties = {CFrame = taggeddoor.PrimaryPart.CFrame * CFrame.Angles(math.rad(-110), 0, 0)} end
            if not Properties2 then Properties2 = {CFrame = taggeddoor.PrimaryPart.CFrame * CFrame.Angles(0, 0, 0)} end

            if not tdooropen then tdooropen = TweenService:Create(taggeddoor.PrimaryPart, TweenInfo, Properties) end
            if not tdoorclose then tdoorclose = TweenService:Create(taggeddoor.PrimaryPart, TweenInfo, Properties2) end

            if not Debounce then
                Debounce = true
                if not InAction then
                    InAction = true
                    tdooropen:Play()
                    taggeddoor.Open:Play()
                else
                    InAction = not InAction
                    tdoorclose:Play()
                    taggeddoor.Close:Play()
                end
                wait(1)
                Debounce = not Debounce
                return
            end    
        end
    end
end)

The client also knows which door should be opened. Send that information as another argument to the FireServer call, and use that to only affect the relevant door.

1 Like

I mean how tho? It’s multiple doors not just one. How I can check if the client has clicked on the relevant door and make it only affected by the Server Script and not others. That’s the hard part for me.

Could you post the client code?

1 Like

I am using Button1Down for a “fake” clickdetector. Because this will help players bypass the tool barrier that is holding the Mouse from clicking on things while holding a tool.

-- [Variables] --
local Player = game:GetService("Players").LocalPlayer
local Mouse = Player:GetMouse()

-- [Services] --
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Debris = game:GetService("Debris")

-- [Setting up] --

local RemoteEvent = ReplicatedStorage:WaitForChild("Door Open")

-- [Events] --

Mouse.Button1Down:Connect(function()
	local Target = Mouse.Target

	if Target and Target.Parent then
		if Target.Parent.Name == "Wooden Door" then
			RemoteEvent:FireServer("Signal")
		end
	end
end)

A few things stand out to me. First, the problem you’re experiencing: When you click on a door, the only info you send to the server is the word “Signal” and nothing else. So the server doesn’t actually know which door you want to open. Then on the server, it just opens the first door in the TaggedDoors table. You need some more info sent to the server so it knows which door to open.

Secondly, you’re creating a lot of global variables within your RemoteEvent handler on the server. This is generally bad practice and might lead to unexpected behavior down the line. I would recommend not doing that if possible.

To fix these things, you could reorient your code so that the client sends the reference of the desired door. The server will then check to make sure that the door is properly tagged, and then will open or close said door. We can store the state of each door in custom attributes.

On the server, you could have something like this:

local doorDebounce = 1

RemoteEvent.OnServerEvent:Connect(function(player, door)

	-- Stop if the player tried to open a non-door:
	if not CollectionService:HasTag(door, "OpenableDoor") then return end

	-- Debounce based on last time the door was opened/closed:
	local lastTimeUsed = door:GetAttribute("LastTimeUsed") or 0
	local now = time()
	if (now - lastTimeUsed) < doorDebounce then return end
	door:SetAttribute("LastTimeUsed", now)

	-- Toggle the IsOpen custom attribute on the door:
	local open = not door:GetAttribute("IsOpen")
	door:SetAttribute("IsOpen", open)

	if open then
		-- Run the tween to open the door
	else
		-- Close the door
	end

end)

On the client, only a couple things change. First, we do a check ourselves to make sure it has the right tag, and then we send along the door instance itself:

Mouse.Button1Down:Connect(function()
	local Target = Mouse.Target

	if Target and Target.Parent and CollectionService:HasTag(Target, "OpenableDoor") then
		if Target.Parent.Name == "Wooden Door" then
			RemoteEvent:FireServer(Target)
		end
	end
end)
2 Likes

Tried your solution and now they are stuck and won’t move.

https://gyazo.com/518cc73163eaa5ca0d9e156d8a2d8f74

I had done setting up all things needed to fix (Attributes and check tags and other stuff) but it kept being stuck and won’t move when being clicked on. What is (are) the possible problem(s) behind this?

Nvm, figured out something to make it works.