How to get all doors and check player distances

I can’t seem to have the game keep track of every door and its distance from all the players. Atm it seems to only look through one door each loop, and none of the doors ever open.

I’m doing this on the server side as I want when one player goes near the door, it opens for everyone

-- Server side
if RunService:IsServer() then
	--[[ Check players and their distance to doors ]]--
	coroutine.wrap(function()
		while true do
			for _, player in pairs(Players:GetPlayers()) do
				local Character = player.Character
				if Character then
					local ClosestDistance = math.huge
					
					-- Check for closest interaction
					for _, door in pairs(CollectionService:GetTagged('Doors')) do
						if door.PrimaryPart and door then
							print(door.Parent)
							print(player:DistanceFromCharacter(door.PrimaryPart.Position), ReachDistance)
							-- See if door is within range
							if player:DistanceFromCharacter(door.PrimaryPart.Position) <= ReachDistance then
								-- Open door
								OpenDoor(door)
								print(4)
							else
								-- Close door
								CloseDoor(door)
							end
						end
					end
				end
			end
			
			wait()
		end
	end)()
end

Output

Pizzeria
1479.1568603516 15
Lighthouse
1543.7940673828 15
Bailey’s Boutiques
1716.2908935547 15
Island Club
1655.1538085938 15
Fred’s Furniture
1383.5015869141 15
Island Delights
1429.1491699219 15
Island Delights
270.92697143555 15
VIP Club
1530.3192138672 15
Pizzeria
302.63830566406 15
Gabrielle’s Cafe
595.84344482422 15
Bailey’s Boutiques
370.03140258789 15
Island Club
368.2978515625 15
Gabrielle’s Cafe
1431.3859863281 15
Lighthouse
691.07061767578 15
Fred’s Furniture
308.18380737305 15
Pizzeria
1479.0899658203 15
Lighthouse
1543.7501220703 15
Bailey’s Boutiques
1716.2922363281 15
Island Club
1655.0765380859 15
Fred’s Furniture
1383.4184570313 15
Island Delights
1429.0695800781 15
Island Delights
270.93014526367 15
VIP Club
1530.3072509766 15
Pizzeria
302.64041137695 15
Gabrielle’s Cafe
595.88616943359 15
Bailey’s Boutiques
370.10104370117 15
Island Club
368.4001159668 15
Gabrielle’s Cafe
1431.4582519531 15
Lighthouse
691.05883789063 15
Fred’s Furniture
308.24383544922 15
Pizzeria
1479.1350097656 15
Lighthouse
1543.7922363281 15
Bailey’s Boutiques
1716.2834472656 15
Island Club
1655.1606445313 15
Fred’s Furniture
1383.5056152344 15
Island Delights
1434.5323486328 15
Island Delights
231.81729125977 15
VIP Club
1425.6922607422 15
Pizzeria
147.18650817871 15
Gabrielle’s Cafe
397.45861816406 15
Bailey’s Boutiques
125.72248840332 15
Island Club
135.06916809082 15
Gabrielle’s Cafe
1222.8717041016 15
Lighthouse
476.92657470703 15

2 Likes

Why not give each door a function to check the distance of itself and all the players?

Also feels a little strenuous on the server to do the distance calculations(although that depends on your usage) so why not let the player do the detection then do a remote event with a server sided check?

Or you could separate the for loops into two separate coroutine wraps like the tutorial one for looping through the player then input that character into another coroutine wrap function for checking the door position.

Edit also what is up with closest distance:

It doesn’t seem to be used. A placeholder?

1 Like

Oop the ClosestDistance I must have left there on accident.

Would it be more efficient doing it client side and then firing a remote to server? And how could I cleanly go about seperating the for loops?

1 Like

I believe you can just seperate the forloops like so, although it’s hard to format the code, lots of nested for loops.

getAllPlayersAndCheckDoor = coroutine.wrap(function()
	for _, player in pairs(Players:GetPlayers()) do
	
        local Character = player.Character
checkDoor(Character)
    end

end)

checkDoor = coroutine.wrap(function(Character)
	    if door.PrimaryPart and door then
        print(door.Parent)
        print(player:DistanceFromCharacter(door.PrimaryPart.Position), ReachDistance)
        -- See if door is within range
        if player:DistanceFromCharacter(door.PrimaryPart.Position) <= ReachDistance then
            -- Open door
            OpenDoor(door)
            print(4)
        else
            -- Close door
            CloseDoor(door)
        end
    end
end)

-- Then do both for loops at the same time
while true do

getAllPlayersAndCheckDoor()

wait(1)

end


1 Like

I get a bunch of red lines doing so



Unless there’s some way I need to connect up my previous code to it?
EDIT I think I figured it out, but I get this error cannot resume dead coroutine

1 Like

well that may not help you much but you can see if it works for you

function Public.ClearDoors()

for _,C in pairs(Private.DoorConnections) do
	if (C ~= nil) then
		C:disconnect();
	end
end

Private.DoorConnections = {};

end

function Public.SetupDoorObject(DoorObject)

DoorObject.Enter.PrimaryPart = DoorObject.Enter.Hinge;
DoorObject.Exit.PrimaryPart = DoorObject.Exit.Hinge;

DoorObject.Enter.IsOpen.Value = false;
DoorObject.Exit.IsOpen.Value = false;

local DoorConfig = DoorObject["Config"];
local DoorVWConfig = Private.Classes.VirtualWorld.GetCurrentVWConfig()["Doors"][DoorConfig["DoorId"].Value];

if (DoorConfig:findFirstChild("OriginalCFrames") == nil) then
	local OriginalCFrames = Instance.new("Folder", DoorConfig);
	OriginalCFrames.Name = "OriginalCFrames";
	
	local EnterCFrame = Instance.new("CFrameValue", OriginalCFrames);
	EnterCFrame.Name = "Enter";
	EnterCFrame.Value = DoorObject.Enter:GetPrimaryPartCFrame(); 
	
	local EnterCFrame = Instance.new("CFrameValue", OriginalCFrames);
	EnterCFrame.Name = "Exit";
	EnterCFrame.Value = DoorObject.Exit:GetPrimaryPartCFrame();
	
	-- Check if there are any NonCollide objects, and mark them as so.
	local function Check( Object )
		
		for _,O in pairs(Object:GetChildren()) do
			if (O:IsA("BasePart") and not O.CanCollide) then
				local CollideOff = Instance.new("BoolValue", O);
				CollideOff.Name = "NoCollide";
			end
			Check( O );
		end
		
	end