Stop run service from doing something more than once

I’m trying to make an auto drive system, I’m detecting when the vehicle has reached the destination by checking if the distance to the destination is less than 30, then I’d call a function to calculate the next destination for the vehicle to go to.

The problem is, when the vehicle is in that distance, it runs the calculation more than once, which causes it to set the destination to the 4th destination after that, instead of that one.

How can I stop it from doing this?

local function onStepped(_, deltaTime: number)
	-- Calculate the direction to the target
	local targetOffset = chassis.CFrame:PointToObjectSpace(target)

	-- Calculate the distance to the target
	local distance = targetOffset.Magnitude
	if distance < 30 then driveCar() return end


local function driveCar()
	local path = pathfinder:FindPath(start, goal)

	if (path) then
		table.insert(path, 1, start)
		table.insert(path, goal)
		for i = num,num do -- Chooses the next destination after the last, every thing driveCar() is called
			if num <= #path then -- Checks if number has gone over the amount of destinations
				local p1 = path[i - 1]
				local p2 = path[i]

				target = p2 -- Sets the target variable to p2, which the renderstepped uses to make the car drive to p2.
			end
		end
		num = num + 1
	else
		warn("Failed to find Path.")
	end
end

What it looks like:

1 Like

You could try adding a debounce

local debounce = false

local function onStepped(_, deltaTime: number)
	-- Calculate the direction to the target
	local targetOffset = chassis.CFrame:PointToObjectSpace(target)

	-- Calculate the distance to the target
	local distance = targetOffset.Magnitude
	if distance < 30 and debounce == false then 
        debounce = true
        driveCar() 
        return
    end

1 Like

Didn’t work. Same result.

30char

I’m confused, why is this happening???

1 Like

I suggest trying to add a wait(0.05) in the for loop after everything is done.

Still didn’t work.

30charactez

Turns out it’s not running multiple times, but it still skips destinations?? I’ve checked with running the driveCar() function every second and it didn’t skip anything, what’s different here?

1 Like

Could you send me the roblox place file? I think I know what’s happening but I need to edit the actual script.

Yeah sure.

DriveNPC.rbxl (859.2 KB)

Drive script is located in the car:
image

It’s skipping all the places where the purple lines are.

1 Like

Fixed it. The start position would constantly update because it is inside the driveCar() function. That’s why the distance between the paths seemed to increase exponentially. It shouldn’t be like that. Simply place the start and goal variable outside the driveCar() function and it should work just fine.

local start = Vector3.new(chassis.Position.X, chassis.Position.Y, chassis.Position.Z)
local goal = game.ReplicatedStorage.WaypointParts.End.Position

local function driveCar()
	--local nodes = workspace:WaitForChild("NodeList")
	--local nodeArray = nodes:GetChildren()
	--local randomNode = nodeArray[math.random(1, #nodeArray)]

	--local goal = randomNode.Value

	local path = pathfinder:FindPath(start, goal)

	if (path) then

		local pathfolder = Instance.new("Folder", workspace)
		pathfolder.Name = "VisualPath"
		print(num)
		for i = num,num do -- Chooses the next destination after the last, every thing driveCar() is called
			if num <= #path then
				local p1 = path[i - 1]
				local p2 = path[i]
				local p = Instance.new("Part", pathfolder)
				p.CanCollide = false
				p.Anchored = true
				p.TopSurface, p.BottomSurface = Enum.SurfaceType.Smooth, Enum.SurfaceType.Smooth
				p.Color = Color3.fromRGB(255, 208, 90)
				p.Size = Vector3.new(pathwidth,1, (p2 - p1).Magnitude)
				p.CFrame = CFrame.new(p1:Lerp(p2, 0.5), p2)
				p.Transparency = .1

				target = p2
			end
		end
		num = num + 1
		--driveCar()
	else
		warn("Failed to find Path.")
	end
end

Like so.

Thank you so much! I wouldn’t have worked it out without you.

1 Like

No problem. Glad to help you out. Also, if the start and goal variables would be outside the driveCar() function, wouldn’t it be more optimized if the path variable is also outside since it doesn’t need to constantly update. In that way, the script won’t have to calculate a new path for a constant start and goal position, thus making it more optimized.

local start = Vector3.new(chassis.Position.X, chassis.Position.Y, chassis.Position.Z)
local goal = game.ReplicatedStorage.WaypointParts.End.Position
local path = pathfinder:FindPath(start, goal)

local function driveCar()
	--local nodes = workspace:WaitForChild("NodeList")
	--local nodeArray = nodes:GetChildren()
	--local randomNode = nodeArray[math.random(1, #nodeArray)]

	--local goal = randomNode.Value



	if (path) then

		local pathfolder = Instance.new("Folder", workspace)
		pathfolder.Name = "VisualPath"
		print(num)
		for i = num,num do -- Chooses the next destination after the last, every thing driveCar() is called
			if num <= #path then
				local p1 = path[i - 1]
				local p2 = path[i]
				local p = Instance.new("Part", pathfolder)
				p.CanCollide = false
				p.Anchored = true
				p.TopSurface, p.BottomSurface = Enum.SurfaceType.Smooth, Enum.SurfaceType.Smooth
				p.Color = Color3.fromRGB(255, 208, 90)
				p.Size = Vector3.new(pathwidth,1, (p2 - p1).Magnitude)
				p.CFrame = CFrame.new(p1:Lerp(p2, 0.5), p2)
				p.Transparency = .1

				target = p2
			end
		end
		num = num + 1
		--driveCar()
	else
		warn("Failed to find Path.")
	end
end
1 Like

Thank you

30charactezzzzzzzzzz

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.