How to check if MoveTo has finished?

Since I have really far MoveTo positions, I run them in a while loop. As MoveTo stops after 8 seconds if goal hasn’t been reached. I have this method, but it’s not too accurate, has distance could sometimes be > 2 but my character wont move

while self.LastMoved == LastMoved do
				if self.PlayerWashing == player then
					break -- Don't affect player being washed
				end

				local GoalCFrame = workspace.Positions[position]:GetPivot()

				player.Character.Humanoid:MoveTo(GoalCFrame.Position)

				local Distance = (player.Character:GetPivot().Position - GoalCFrame.Position).Magnitude
				if Distance <= 2 then
					player.Character:PivotTo(
						CFrame.new(
							Vector3.new(GoalCFrame.X, GoalCFrame.Y + 2, GoalCFrame.Z),
							GoalCFrame.Position + (GoalCFrame.LookVector * 100)
						)
					)

					break
				end

				task.wait(0.1)
			end
1 Like

You are looking for Humanoid.MoveToFinished, it fires when the player finishes the MoveTo()

1 Like

Please read my post and not just the title. MoveToFinished will not fire in this instance

1 Like

Alr, so ur script looks correct to me but try this:

while self.LastMoved == LastMoved do
	if self.PlayerWashing == player then
		break -- Don't affect player being washed
	end

	local GoalCFrame = workspace.Positions[position]:GetPivot()
	local humanoid = player.Character.Humanoid

	while (player.Character:GetPivot().Position - GoalCFrame.Position).Magnitude > 2 do
		humanoid:MoveTo(GoalCFrame.Position)
		task.wait(0.1)
	end

	player.Character:PivotTo(
		CFrame.new(
			Vector3.new(GoalCFrame.X, GoalCFrame.Y + 2, GoalCFrame.Z),
			GoalCFrame.Position + (GoalCFrame.LookVector * 100)
		)
	)

	break
end
2 Likes

wouldnt it be better to create a temporary part thats for example 2x10x2 studs and just check if the character collided with it

And it’s not teleporting you to the goal either?

(CFrame.new(pos, lookAt))

In this case you should use CFrame.lookAt, but you can also shorten it with CFrame.lookAlong:

CFrame.lookAlong(
	Vector3.new(GoalCFrame.X, GoalCFrame.Y + 2, GoalCFrame.Z),
	GoalCFrame.LookVector
)

Why wouldn’t you use a MoveToFinished. Your Question is literally saying:
How to check if MOVETO has FINISHED. Is it the Pivot thing?

Quick test in a client script seems to work fine.

local player = game:GetService("Players").LocalPlayer
local pivot, GoalCFrame = nil, nil

local function MovePlayerToPosition(player, goal)
	local humanoid = player.Character.Humanoid
	
	humanoid:MoveTo(goal)
	humanoid.MoveToFinished:Connect(function(reached)
		if reached then pivot = CFrame.new(goal)
			player.Character:PivotTo(CFrame.new(
				Vector3.new(pivot.X, pivot.Y + 2, pivot.Z),
					pivot.Position + (pivot.LookVector * 100)
				)
			)
		end
	end)
end

task.wait(2)-- stall to see test.
GoalCFrame = Vector3.new(114.125, 1.5, -0.54)
MovePlayerToPosition(player, GoalCFrame)

Change the vector3 to your workspace.Positions[] instead of a vector3.new …

again, the question states

Which means I HAVE to be firing MoveTo in a while loop which means MoveToFinished never fires

Well that didn’t sink in at 1st, I didn’t even know that, always used waypoints or tweens.
But that sure clears up a few errors I’ve had in the past with moveto().
Best I could get was almost like yours with very slight changes…
(Including eliminating the chance of server lag and a CD stall)

--Client Test Script 
local player=game.Players.LocalPlayer
local character=player.Character or player.CharacterAdded:Wait()
local LastMoved,GF,CD,position=tick(),nil,nil,1
local self={LastMoved=LastMoved,PlayerWashing=nil}
while self.LastMoved==LastMoved do task.wait(0.05)
    if self.PlayerWashing==player then break end
	GF=workspace.Positions[position]:GetPivot()character.Humanoid:MoveTo(GF.Position)
	task.wait(0.1)CD=(character:GetPivot().Position-GF.Position).Magnitude --CD stalled
	if CD<2 then character:PivotTo(CFrame.new(GF.X,GF.Y+2,GF.Z,GF.LookVector*100))break
	end task.wait(0.05)
end