:MoveTo() takes a second to start

I have a monster similar to SCP 173 or a weeping angel, only moves when your not looking. However, every time he starts moving it takes him a very short moment to get started. It’s not the worst, but it’s noticeable, and undesirable.

I thought maybe it was because he was recomputing his path every time, but I put prints after computing and getting the waypoints of a path, and those prints go off instantly when you look away.

The problem is with the :moveto. Is there anyway to fix this?

Video of the problem:


BTW: the error in the output has to do with the killbox around him, NOT his pathfinding! that error is unrelated please do not reply about it!!

This is the movescript:

local RS = game:GetService("ReplicatedStorage")
local PathFindingService = game:GetService("PathfindingService")

local Path = PathFindingService:CreatePath({
	AgentRadius = 1, 
	AgentHeight = 2.5, 
	AgentCanJump = false,
	AgentCanClimb = true
})

if not game.Players:GetChildren()[1].Character then
	game.Players:GetChildren()[1].CharacterAdded:Wait()
end

while task.wait() do
	Path:ComputeAsync(script.Parent.Parent.Parent.HumanoidRootPart.Position, game.Players:GetChildren()[1].Character:WaitForChild("HumanoidRootPart").Position + (game.Players:GetChildren()[1].Character.Humanoid.MoveDirection * 3))
	print("computeasync")
	local waypoints = Path:GetWaypoints()
	print("got waypoints")
	for i, waypoint: PathWaypoint in pairs(waypoints) do
		script.Parent.Parent:MoveTo(waypoint.Position)
		print("moving")
		script.Parent.Parent.MoveToFinished:Wait()
	end
end

This is the script that lets the character move when unseen.

---------- Services ----------

local RS = game:GetService("ReplicatedStorage")
local Check = require(game.ServerScriptService.Check)

---------- Variables ----------

local Observed = script.Observed

---------- Functionality ----------

RS.ObserveChange.OnServerEvent:Connect(function(plr, monster, seen)
	if Check.SanityChecks({monster, seen}) then
		if not seen then
			for i, v in pairs(script.Parent.Parent:GetChildren()) do
				if v.ClassName == "Part" then
					v.BrickColor = BrickColor.new("Maroon")
					v.Anchored = false
				end
			end
			script.Parent.Parent.HumanoidRootPart:SetNetworkOwner(nil)
			script.Parent.Parent.Kill.Script.Enabled = true
		else
			for i, v in pairs(script.Parent.Parent:GetChildren()) do
				if v.ClassName == "Part" then
					v.Color = Color3.new(0,0,0)
					v.Anchored = true
				end
			end
			script.Parent.Parent.Kill.Script.Enabled = false
			script.Parent:MoveTo(script.Parent.Parent.HumanoidRootPart.Position)
		end
	end
end)

Any help is appreciated!

anchor the character when it was seen by the player, deanchor them if the player never seen the character.

This is already happening, I should’ve mentioned that in the original post, sorry.
The movescript is enabled only when the player is not looking by another script, I tried changing it to always be enabled but it still has the slightly delayed start…
Here’s the script that anchors and unanchors:

---------- Services ----------

local RS = game:GetService("ReplicatedStorage")
local Check = require(game.ServerScriptService.Check)

---------- Variables ----------

local Observed = script.Observed

---------- Functionality ----------

RS.ObserveChange.OnServerEvent:Connect(function(plr, monster, seen)
	if Check.SanityChecks({monster, seen}) then
		if not seen then
			for i, v in pairs(script.Parent.Parent:GetChildren()) do
				if v.ClassName == "Part" then
					v.BrickColor = BrickColor.new("Maroon")
					v.Anchored = false
				end
			end
			script.Parent.Parent.HumanoidRootPart:SetNetworkOwner(nil)
			script.Parent.Parent.Kill.Script.Enabled = true
		else
			for i, v in pairs(script.Parent.Parent:GetChildren()) do
				if v.ClassName == "Part" then
					v.Color = Color3.new(0,0,0)
					v.Anchored = true
				end
			end
			script.Parent.Parent.Kill.Script.Enabled = false
			script.Parent:MoveTo(script.Parent.Parent.HumanoidRootPart.Position)
		end
	end
end)

Could be. cause you’re yielding the while loop here

Shouldn’t you use path:ComputeAsync() under a pcall?

local RS = game:GetService("ReplicatedStorage")
local PathFindingService = game:GetService("PathfindingService")

local Path = PathFindingService:CreatePath({
	AgentRadius = 1, 
	AgentHeight = 2.5, 
	AgentCanJump = false,
	AgentCanClimb = true
})

if not game.Players:GetChildren()[1].Character then
	game.Players:GetChildren()[1].CharacterAdded:Wait()
end

while task.wait() do
	local success, err = pcall(function()
		Path:ComputeAsync(script.Parent.Parent.Parent.HumanoidRootPart.Position, game.Players:GetChildren()[1].Character:WaitForChild("HumanoidRootPart").Position + (game.Players:GetChildren()[1].Character.Humanoid.MoveDirection * 3))
	end)
	
	if success and Path.Status == Enum.PathStatus.Success then
		print("computeasync")
		local waypoints = Path:GetWaypoints()
		print("got waypoints")
		for i, waypoint: PathWaypoint in pairs(waypoints) do
			script.Parent.Parent:MoveTo(waypoint.Position)
			print("moving")
			script.Parent.Parent.MoveToFinished:Wait()
		end
	end
end