Right now how im doing it is i just check the position of each part and then check which part is closest to the players hrp but with a few interactable parts the code ran pretty fast like (0.07ms) but when i tested it and added a bunch more (536) the code run time jumped up to (.25ms) and i run this function every .1s in a while loop making it pretty expensive now does anyone have a better approach of checking what part in a table of parts is the closest to the player cheaply?
local collectionService = game:GetService("CollectionService")
local effectsManagerModule = require(script.Parent.EffectsManager)
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local RANGE_SQUARED = 64 --that means the range is 8 studs (8*8=64)
local interactables = {}
local currentInteractable
player.CharacterAdded:Connect(function(newCharacter)
character = newCharacter
humanoidRootPart = newCharacter:WaitForChild("HumanoidRootPart")
currentInteractable = nil
end)
for _, interactable in pairs(collectionService:GetTagged("Interactable")) do
interactables[interactable] = true
end
collectionService:GetInstanceAddedSignal("Interactable"):Connect(function(interactable)
interactables[interactable] = true
end)
collectionService:GetInstanceRemovedSignal("Interactable"):Connect(function(interactable)
interactables[interactable] = nil
if currentInteractable == interactable then
currentInteractable = nil
effectsManagerModule.removeEffects()
end
end)
return function()
if not (humanoidRootPart and next(interactables)) then
return
end
local humanoidRootPartPosition = humanoidRootPart.Position
local closestDistSq = RANGE_SQUARED
local closestInteractable = nil
for interactable in interactables do
if not interactable then
continue
end
local difference = humanoidRootPartPosition - interactable.Position
local distSq = difference:Dot(difference)
if distSq >= closestDistSq then
continue
end
closestDistSq = distSq
closestInteractable = interactable
if distSq == 0 then
break
end
end
if closestInteractable == currentInteractable then
return currentInteractable
end
effectsManagerModule.removeEffects()
currentInteractable = closestInteractable
effectsManagerModule.applyEffects(currentInteractable)
return currentInteractable
end