Currently I’m working on a door opening system which uses the distance of the player from the door. My map is relatively large and consists of many doors.
What would be the most efficient way to get a players closest distance to a door? Looping through every doors position would be an option but I’m wondering if there’s any better solution?
First do this on the client for sure. That way the server isn’t checking everyone all the time and secondly you could split the space up into regions and only check doors in or near the same region as the player.
I’m curious of if your system could implement Proximity Prompts because if so they could be more performance friendly than probably all manual solutions, while also being more convenient.
You can also set the Style to Custom to use your own prompt UI while also being allowed to use the Proximity Prompt API.
The doors currently swing freely meaning players can walk right through them. Why I need distance is because the player has an animation while walking through the door, and I use the distance to figure out how far into the animation the player should be.
maybe use a door.touched event and then loop (player.head.position - door.position).Magnitude to get the distance and break the loop when the distance is pre far
local players = game:GetService("Players")
local doorPositions, playersClosestDoor = {}, {}
local function getDoorPositions()
doorPositions = {}
for _, door in ipairs(workspace:GetChildren()) do
if door:IsA("BasePart") then --assume the door is a part instance
if door.Name == "Door" then --assume its name is "Door"
doorPositions[door] = door.Position
end
end
end
end
local function findAllClosestDoor()
playersClosestDoor = {}
for _, player in ipairs(players:GetPlayers()) do
local closestDoor, closestDistance = nil, math.huge
for doorInstance, doorPosition in pairs(doorPositions) do
local distance = player:DistanceFromCharacter(doorPosition)
if distance < closestDistance then
closestDoor = doorInstance
closestDistance = distance
end
end
if closestDoor then
playersClosestDoor[player] = closestDoor
end
end
end
local function findOneClosestDoor(player)
playersClosestDoor[player] = nil
local closestDoor, closestDistance = nil, math.huge
for doorInstance, doorPosition in pairs(doorPositions) do
local distance = player:DistanceFromCharacter(doorPosition)
if distance < closestDistance then
closestDoor = doorInstance
closestDistance = distance
end
end
if closestDoor then
playersClosestDoor[player] = closestDoor
end
end
Here’s an example script I just wrote which tackles your question. Iterating over a table of door positions is very fast, minimal delay would only ever be observed if you had thousands and thousands of doors.
Sorry the the late response. I ended up doing something similar to this. Instead of zones, I loop through every door every x amount of seconds, and then doors only within a certain range will be looped through at a higher rate to find the distance. Thanks!