I’m trying to get a constant loop of all the doors in my game, and basically stop the loop when a door is found, and the player is near said door, but still be able to track wheether the player gets closer to a different door, or has moved away from the current door
local function RenderStepped()
local Character = Player.Character
if Character then
local HumanoidRootPart = Character:FindFirstChild('HumanoidRootPart')
if not HumanoidRootPart then return end
for _, v in pairs(AllDoors) do
Distance = (v.CFrame.Position - HumanoidRootPart.CFrame.Position).magnitude
if not Door or Distance <= 8 then
Door = v
end
end
end
if Door then
print('Nearest door', Door) -- SHOULD ONLY PRINT ONCE!, not constantly
end
end
Is there any particular reason you want to lock up the GPU for this task? You named the function RenderStepped which implies you intend on running it on the render cycle.
If you just want to find the nearest door then record the minimum distance so far and iterate over the set of doors. If the initial minimum distance is replaced with 8 then it will not find any door if none are closer than 8 away.
local function GetNearestDoor()
local Character = Player.Character
if not Character then return end
local HumanoidRootPart = Character:FindFirstChild('HumanoidRootPart')
if not HumanoidRootPart then return end
local minDistance, door = math.huge, nil
for _, v in pairs(AllDoors) do
local distance = (v.Position - HumanoidRootPart.Position).Magnitude
if distance < minDistance then
minDistance, door = distance, v
end
end
return door
end
It is being run by RenderStepped, so ye. Reason I don’t want it constantly looping is because I want to try tweening the door, and if its constantly looping, the door just keep tweening, and I’m unsure how to go about fixing that problem
Kinda made another post here on the whole door tweening problem
local function GetNearestDoor()
local Character = Player.Character
if not Character then return end
local HumanoidRootPart = Character:FindFirstChild('HumanoidRootPart')
if not HumanoidRootPart then return end
local minDistance, door = 8, nil
for _, v in pairs(AllDoors) do
local distance = (v.Position - HumanoidRootPart.Position).Magnitude
if distance < minDistance then
minDistance, door = distance, v
end
end
return door
end
local function RenderStepped()
local Door = GetNearestDoor()
if Door then
print(Door)
end
end
There isn’t really any easy way to improve finding the nearest door better than a constant loop. Synchronizing it with the screen’s framerate is completely unnecessary.
The problem you want to solve is to have an event-driven type system where you only do something when the status of whether or not a particular door is in range changes. This can be done using a loop in its own thread and a BindableEvent.
local NearestDoorChanged = Instance.new("BindableEvent")
coroutine.wrap(function()
local nearestDoor = nil
while true do
local door = GetNearestDoor()
if nearestDoor ~= door then
nearestDoor = door
NearestDoorChanged:Fire(door)
end
wait(.1)
end
end)()
NearestDoorChanged.Event:Connect(function(door)
print("door: "..tostring(door))
end)
I’ve never really used coroutines before, but guessing it just allows the loop to continue running while allowing the code after to run as well. Could I use a spawn() function instead??