local function B(B,v,C)local l={}local T local W if C~=nil then T=C W=C else T=UseDirectPath W=UseDirectPathForVehicle end l.Cancelled=false l.Started=false l.Finished=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")l.PathFailed=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")l.PathComputing=false l.PathComputed=false l.OriginalTargetPoint=B l.TargetPoint=B l.TargetSurfaceNormal=v l.DiedConn=nil l.SeatedConn=nil l.BlockedConn=nil l.TeleportedConn=nil l.CurrentPoint=0 l.HumanoidOffsetFromPath=ZERO_VECTOR3 l.CurrentWaypointPosition=nil l.CurrentWaypointPlaneNormal=ZERO_VECTOR3 l.CurrentWaypointPlaneDistance=0 l.CurrentWaypointNeedsJump=false l.CurrentHumanoidPosition=ZERO_VECTOR3 l.CurrentHumanoidVelocity=0 l.NextActionMoveDirection=ZERO_VECTOR3 l.NextActionJump=false l.Timeout=0 l.Humanoid=findPlayerHumanoid(Player)l.OriginPoint=nil l.AgentCanFollowPath=false l.DirectPath=false l.DirectPathRiseFirst=false local s=l.Humanoid and l.Humanoid.RootPart if s then l.OriginPoint=s.CFrame.p local B=2 local v=5 local C=true local Y=l.Humanoid.SeatPart if Y and Y:IsA("\086\101\104\105\099\108\101\083\101\097\116")then local T=Y:FindFirstAncestorOfClass("\077\111\100\101\108")if T then local s=T.PrimaryPart T.PrimaryPart=Y if W then local s=T:GetExtentsSize()B=(AgentSizeIncreaseFactor*.5)*math.sqrt(s.X*s.X+s.Z*s.Z)v=AgentSizeIncreaseFactor*s.Y C=false l.AgentCanFollowPath=true l.DirectPath=W end T.PrimaryPart=s end else local W if FFlagUserExcludeNonCollidableForPathfinding then local B=GetCharacter()if B~=nil then W=getCollidableExtentsSize(B)end end if W==nil then W=(GetCharacter()):GetExtentsSize()end B=(AgentSizeIncreaseFactor*.5)*math.sqrt(W.X*W.X+W.Z*W.Z)v=AgentSizeIncreaseFactor*W.Y C=l.Humanoid.JumpPower>0 l.AgentCanFollowPath=true l.DirectPath=T l.DirectPathRiseFirst=l.Humanoid.Sit end l.pathResult=PathfindingService:CreatePath({AgentRadius=B,AgentHeight=v;AgentCanJump=C})end function l.Cleanup(B)if l.stopTraverseFunc then l.stopTraverseFunc()l.stopTraverseFunc=nil end if l.MoveToConn then l.MoveToConn:Disconnect()l.MoveToConn=nil end if l.BlockedConn then l.BlockedConn:Disconnect()l.BlockedConn=nil end if l.DiedConn then l.DiedConn:Disconnect()l.DiedConn=nil end if l.SeatedConn then l.SeatedConn:Disconnect()l.SeatedConn=nil end if l.TeleportedConn then l.TeleportedConn:Disconnect()l.TeleportedConn=nil end l.Started=false end function l.Cancel(B)l.Cancelled=true l:Cleanup()end function l.IsActive(B)return l.AgentCanFollowPath and(l.Started and not l.Cancelled)end function l.OnPathInterrupted(B)l.Cancelled=true l:OnPointReached(false)end function l.ComputePath(B)if l.OriginPoint then if l.PathComputed or l.PathComputing then return end l.PathComputing=true if l.AgentCanFollowPath then if l.DirectPath then l.pointList={PathWaypoint.new(l.OriginPoint,Enum.PathWaypointAction.Walk),PathWaypoint.new(l.TargetPoint,l.DirectPathRiseFirst and Enum.PathWaypointAction.Jump or Enum.PathWaypointAction.Walk)}l.PathComputed=true else l.pathResult:ComputeAsync(l.OriginPoint,l.TargetPoint)l.pointList=l.pathResult:GetWaypoints()l.BlockedConn=l.pathResult.Blocked:Connect(function(B)l:OnPathBlocked(B)end)l.PathComputed=l.pathResult.Status==Enum.PathStatus.Success end end l.PathComputing=false end end function l.IsValidPath(B)l:ComputePath()return l.PathComputed and l.AgentCanFollowPath end l.Recomputing=false function l.OnPathBlocked(v,B)local C=B>=l.CurrentPoint if not C or l.Recomputing then return end l.Recomputing=true if l.stopTraverseFunc then l.stopTraverseFunc()l.stopTraverseFunc=nil end l.OriginPoint=l.Humanoid.RootPart.CFrame.p l.pathResult:ComputeAsync(l.OriginPoint,l.TargetPoint)l.pointList=l.pathResult:GetWaypoints()if#l.pointList>0 then l.HumanoidOffsetFromPath=l.pointList[1].Position-l.OriginPoint end l.PathComputed=l.pathResult.Status==Enum.PathStatus.Success if ShowPath then l.stopTraverseFunc,l.setPointFunc=ClickToMoveDisplay.CreatePathDisplay(l.pointList)end if l.PathComputed then l.CurrentPoint=1 l:OnPointReached(true)else l.PathFailed:Fire()l:Cleanup()end l.Recomputing=false end function l.OnRenderStepped(v,B)if l.Started and not l.Cancelled then l.Timeout=l.Timeout+B if l.Timeout>UnreachableWaypointTimeout then l:OnPointReached(false)return end l.CurrentHumanoidPosition=l.Humanoid.RootPart.Position+l.HumanoidOffsetFromPath l.CurrentHumanoidVelocity=l.Humanoid.RootPart.Velocity while l.Started and l:IsCurrentWaypointReached()do l:OnPointReached(true)end if l.Started then l.NextActionMoveDirection=l.CurrentWaypointPosition-l.CurrentHumanoidPosition if l.NextActionMoveDirection.Magnitude>ALMOST_ZERO then l.NextActionMoveDirection=l.NextActionMoveDirection.Unit else l.NextActionMoveDirection=ZERO_VECTOR3 end if l.CurrentWaypointNeedsJump then l.NextActionJump=true l.CurrentWaypointNeedsJump=false else l.NextActionJump=false end end end end function l.IsCurrentWaypointReached(B)local v=false if l.CurrentWaypointPlaneNormal~=ZERO_VECTOR3 then local B=l.CurrentWaypointPlaneNormal:Dot(l.CurrentHumanoidPosition)-l.CurrentWaypointPlaneDistance local C=-l.CurrentWaypointPlaneNormal:Dot(l.CurrentHumanoidVelocity)local T=math.max(1.0,.0625*C)v=B<T else v=true end if v then l.CurrentWaypointPosition=nil l.CurrentWaypointPlaneNormal=ZERO_VECTOR3 l.CurrentWaypointPlaneDistance=0 end return v end function l.OnPointReached(v,B)if B and not l.Cancelled then if l.setPointFunc then l.setPointFunc(l.CurrentPoint)end local B=l.CurrentPoint+1 if B>#l.pointList then if l.stopTraverseFunc then l.stopTraverseFunc()end l.Finished:Fire()l:Cleanup()else local v=l.pointList[l.CurrentPoint]local C=l.pointList[B]local T=l.Humanoid:GetState()local W=T==Enum.HumanoidStateType.FallingDown or T==Enum.HumanoidStateType.Freefall or T==Enum.HumanoidStateType.Jumping if W then local B=C.Action==Enum.PathWaypointAction.Jump if not B and l.CurrentPoint>1 then local T=l.pointList[l.CurrentPoint-1]local W=v.Position-T.Position local s=C.Position-v.Position local Y=(Vector2.new(W.x,W.z)).Unit local G=(Vector2.new(s.x,s.z)).Unit local q=.996 B=Y:Dot(G)<q end if B then l.Humanoid.FreeFalling:Wait()wait(.1)end end l:MoveToNextWayPoint(v,C,B)end else l.PathFailed:Fire()l:Cleanup()end end function l.MoveToNextWayPoint(T,B,v,C)l.CurrentWaypointPlaneNormal=B.Position-v.Position l.CurrentWaypointPlaneNormal=Vector3.new(l.CurrentWaypointPlaneNormal.X,0,l.CurrentWaypointPlaneNormal.Z)if l.CurrentWaypointPlaneNormal.Magnitude>ALMOST_ZERO then l.CurrentWaypointPlaneNormal=l.CurrentWaypointPlaneNormal.Unit l.CurrentWaypointPlaneDistance=l.CurrentWaypointPlaneNormal:Dot(v.Position)else l.CurrentWaypointPlaneNormal=ZERO_VECTOR3 l.CurrentWaypointPlaneDistance=0 end l.CurrentWaypointNeedsJump=v.Action==Enum.PathWaypointAction.Jump l.CurrentWaypointPosition=v.Position l.CurrentPoint=C l.Timeout=0 end function l.Start(v,B)if not l.AgentCanFollowPath then l.PathFailed:Fire()return end if l.Started then return end l.Started=true ClickToMoveDisplay.CancelFailureAnimation()if ShowPath then if B==nil or B then l.stopTraverseFunc,l.setPointFunc=ClickToMoveDisplay.CreatePathDisplay(l.pointList,l.OriginalTargetPoint)end end if#l.pointList>0 then l.HumanoidOffsetFromPath=Vector3.new(0,l.pointList[1].Position.Y-l.OriginPoint.Y,0)l.CurrentHumanoidPosition=l.Humanoid.RootPart.Position+l.HumanoidOffsetFromPath l.CurrentHumanoidVelocity=l.Humanoid.RootPart.Velocity l.SeatedConn=l.Humanoid.Seated:Connect(function(B,v)l:OnPathInterrupted()end)l.DiedConn=l.Humanoid.Died:Connect(function()l:OnPathInterrupted()end)l.TeleportedConn=(l.Humanoid.RootPart:GetPropertyChangedSignal("\067\070\114\097\109\101")):Connect(function()l:OnPathInterrupted()end)l.CurrentPoint=1 l:OnPointReached(true)else l.PathFailed:Fire()if l.stopTraverseFunc then l.stopTraverseFunc()end end end local Y=l.TargetPoint+l.TargetSurfaceNormal*1.5 local G=Ray.new(Y,Vector3.new(0,-1,0)*50)local q,Q=Workspace:FindPartOnRayWithIgnoreList(G,getIgnoreList())if q then l.TargetPoint=Q end l:ComputePath()return l end


local function Pather(endPoint, surfaceNormal, overrideUseDirectPath)
	local this = {}

	local directPathForHumanoid
	local directPathForVehicle
	if overrideUseDirectPath ~= nil then
		directPathForHumanoid = overrideUseDirectPath
		directPathForVehicle = overrideUseDirectPath
	else
		directPathForHumanoid = UseDirectPath
		directPathForVehicle = UseDirectPathForVehicle
	end

	this.Cancelled = false
	this.Started = false

	this.Finished = Instance.new("BindableEvent")
	this.PathFailed = Instance.new("BindableEvent")

	this.PathComputing = false
	this.PathComputed = false

	this.OriginalTargetPoint = endPoint
	this.TargetPoint = endPoint
	this.TargetSurfaceNormal = surfaceNormal

	this.DiedConn = nil
	this.SeatedConn = nil
	this.BlockedConn = nil
	this.TeleportedConn = nil

	this.CurrentPoint = 0

	this.HumanoidOffsetFromPath = ZERO_VECTOR3

	this.CurrentWaypointPosition = nil
	this.CurrentWaypointPlaneNormal = ZERO_VECTOR3
	this.CurrentWaypointPlaneDistance = 0
	this.CurrentWaypointNeedsJump = false;

	this.CurrentHumanoidPosition = ZERO_VECTOR3
	this.CurrentHumanoidVelocity = 0

	this.NextActionMoveDirection = ZERO_VECTOR3
	this.NextActionJump = false

	this.Timeout = 0

	this.Humanoid = findPlayerHumanoid(Player)
	this.OriginPoint = nil
	this.AgentCanFollowPath = false
	this.DirectPath = false
	this.DirectPathRiseFirst = false

	local rootPart = this.Humanoid and this.Humanoid.RootPart
	if rootPart then
		-- Setup origin
		this.OriginPoint = rootPart.CFrame.p

		-- Setup agent
		local agentRadius = 2
		local agentHeight = 5
		local agentCanJump = true

		local seat = this.Humanoid.SeatPart
		if seat and seat:IsA("VehicleSeat") then
			-- Humanoid is seated on a vehicle
			local vehicle = seat:FindFirstAncestorOfClass("Model")
			if vehicle then
				-- Make sure the PrimaryPart is set to the vehicle seat while we compute the extends.
				local tempPrimaryPart = vehicle.PrimaryPart
				vehicle.PrimaryPart = seat

				-- For now, only direct path
				if directPathForVehicle then
					local extents = vehicle:GetExtentsSize()
					agentRadius = AgentSizeIncreaseFactor * 0.5 * math.sqrt(extents.X * extents.X + extents.Z * extents.Z)
					agentHeight = AgentSizeIncreaseFactor * extents.Y
					agentCanJump = false
					this.AgentCanFollowPath = true
					this.DirectPath = directPathForVehicle
				end

				-- Reset PrimaryPart
				vehicle.PrimaryPart = tempPrimaryPart
			end
		else
			local extents
			if FFlagUserExcludeNonCollidableForPathfinding then
				local character = GetCharacter()
				if character ~= nil then
					extents = getCollidableExtentsSize(character)
				end
			end
			if extents == nil then
				extents = GetCharacter():GetExtentsSize()
			end
			agentRadius = AgentSizeIncreaseFactor * 0.5 * math.sqrt(extents.X * extents.X + extents.Z * extents.Z)
			agentHeight = AgentSizeIncreaseFactor * extents.Y
			agentCanJump = (this.Humanoid.JumpPower > 0)
			this.AgentCanFollowPath = true
			this.DirectPath = directPathForHumanoid
			this.DirectPathRiseFirst = this.Humanoid.Sit
		end

		-- Build path object
		this.pathResult = PathfindingService:CreatePath({AgentRadius = agentRadius, AgentHeight = agentHeight, AgentCanJump = agentCanJump})
	end

	function this:Cleanup()
		if this.stopTraverseFunc then
			this.stopTraverseFunc()
			this.stopTraverseFunc = nil
		end

		if this.MoveToConn then
			this.MoveToConn:Disconnect()
			this.MoveToConn = nil
		end

		if this.BlockedConn then
			this.BlockedConn:Disconnect()
			this.BlockedConn = nil
		end

		if this.DiedConn then
			this.DiedConn:Disconnect()
			this.DiedConn = nil
		end

		if this.SeatedConn then
			this.SeatedConn:Disconnect()
			this.SeatedConn = nil
		end

		if this.TeleportedConn then
			this.TeleportedConn:Disconnect()
			this.TeleportedConn = nil
		end

		this.Started = false
	end

	function this:Cancel()
		this.Cancelled = true
		this:Cleanup()
	end

	function this:IsActive()
		return this.AgentCanFollowPath and this.Started and not this.Cancelled
	end

	function this:OnPathInterrupted()
		-- Stop moving
		this.Cancelled = true
		this:OnPointReached(false)
	end

	function this:ComputePath()
		if this.OriginPoint then
			if this.PathComputed or this.PathComputing then return end
			this.PathComputing = true
			if this.AgentCanFollowPath then
				if this.DirectPath then
					this.pointList = {
						PathWaypoint.new(this.OriginPoint, Enum.PathWaypointAction.Walk),
						PathWaypoint.new(this.TargetPoint, this.DirectPathRiseFirst and Enum.PathWaypointAction.Jump or Enum.PathWaypointAction.Walk)
					}
					this.PathComputed = true
				else
					this.pathResult:ComputeAsync(this.OriginPoint, this.TargetPoint)
					this.pointList = this.pathResult:GetWaypoints()
					this.BlockedConn = this.pathResult.Blocked:Connect(function(blockedIdx) this:OnPathBlocked(blockedIdx) end)
					this.PathComputed = this.pathResult.Status == Enum.PathStatus.Success
				end
			end
			this.PathComputing = false
		end
	end

	function this:IsValidPath()
		this:ComputePath()
		return this.PathComputed and this.AgentCanFollowPath
	end

	this.Recomputing = false
	function this:OnPathBlocked(blockedWaypointIdx)
		local pathBlocked = blockedWaypointIdx >= this.CurrentPoint
		if not pathBlocked or this.Recomputing then
			return
		end

		this.Recomputing = true

		if this.stopTraverseFunc then
			this.stopTraverseFunc()
			this.stopTraverseFunc = nil
		end

		this.OriginPoint = this.Humanoid.RootPart.CFrame.p

		this.pathResult:ComputeAsync(this.OriginPoint, this.TargetPoint)
		this.pointList = this.pathResult:GetWaypoints()
		if #this.pointList > 0 then
			this.HumanoidOffsetFromPath = this.pointList[1].Position - this.OriginPoint
		end
		this.PathComputed = this.pathResult.Status == Enum.PathStatus.Success

		if ShowPath then
			this.stopTraverseFunc, this.setPointFunc = ClickToMoveDisplay.CreatePathDisplay(this.pointList)
		end
		if this.PathComputed then
			this.CurrentPoint = 1 -- The first waypoint is always the start location. Skip it.
			this:OnPointReached(true) -- Move to first point
		else
			this.PathFailed:Fire()
			this:Cleanup()
		end

		this.Recomputing = false
	end

	function this:OnRenderStepped(dt)
		if this.Started and not this.Cancelled then
			-- Check for Timeout (if a waypoint is not reached within the delay, we fail)
			this.Timeout = this.Timeout + dt
			if this.Timeout > UnreachableWaypointTimeout then
				this:OnPointReached(false)
				return
			end

			-- Get Humanoid position and velocity
			this.CurrentHumanoidPosition = this.Humanoid.RootPart.Position + this.HumanoidOffsetFromPath
			this.CurrentHumanoidVelocity = this.Humanoid.RootPart.Velocity

			-- Check if it has reached some waypoints
			while this.Started and this:IsCurrentWaypointReached() do
				this:OnPointReached(true)
			end

			-- If still started, update actions
			if this.Started then
				-- Move action
				this.NextActionMoveDirection = this.CurrentWaypointPosition - this.CurrentHumanoidPosition
				if this.NextActionMoveDirection.Magnitude > ALMOST_ZERO then
					this.NextActionMoveDirection = this.NextActionMoveDirection.Unit
				else
					this.NextActionMoveDirection = ZERO_VECTOR3
				end
				-- Jump action
				if this.CurrentWaypointNeedsJump then
					this.NextActionJump = true
					this.CurrentWaypointNeedsJump = false	-- Request jump only once
				else
					this.NextActionJump = false
				end
			end
		end
	end

	function this:IsCurrentWaypointReached()
		local reached = false

		-- Check we do have a plane, if not, we consider the waypoint reached
		if this.CurrentWaypointPlaneNormal ~= ZERO_VECTOR3 then
			-- Compute distance of Humanoid from destination plane
			local dist = this.CurrentWaypointPlaneNormal:Dot(this.CurrentHumanoidPosition) - this.CurrentWaypointPlaneDistance
			-- Compute the component of the Humanoid velocity that is towards the plane
			local velocity = -this.CurrentWaypointPlaneNormal:Dot(this.CurrentHumanoidVelocity)
			-- Compute the threshold from the destination plane based on Humanoid velocity
			local threshold = math.max(1.0, 0.0625 * velocity)
			-- If we are less then threshold in front of the plane (between 0 and threshold) or if we are behing the plane (less then 0), we consider we reached it
			reached = dist < threshold
		else
			reached = true
		end

		if reached then
			this.CurrentWaypointPosition = nil
			this.CurrentWaypointPlaneNormal	= ZERO_VECTOR3
			this.CurrentWaypointPlaneDistance = 0
		end

		return reached
	end

	function this:OnPointReached(reached)

		if reached and not this.Cancelled then
			-- First, destroyed the current displayed waypoint
			if this.setPointFunc then
				this.setPointFunc(this.CurrentPoint)
			end

			local nextWaypointIdx = this.CurrentPoint + 1

			if nextWaypointIdx > #this.pointList then
				-- End of path reached
				if this.stopTraverseFunc then
					this.stopTraverseFunc()
				end
				this.Finished:Fire()
				this:Cleanup()
			else
				local currentWaypoint = this.pointList[this.CurrentPoint]
				local nextWaypoint = this.pointList[nextWaypointIdx]

				-- If airborne, only allow to keep moving
				-- if nextWaypoint.Action ~= Jump, or path mantains a direction
				-- Otherwise, wait until the humanoid gets to the ground
				local currentState = this.Humanoid:GetState()
				local isInAir = currentState == Enum.HumanoidStateType.FallingDown
					or currentState == Enum.HumanoidStateType.Freefall
					or currentState == Enum.HumanoidStateType.Jumping

				if isInAir then
					local shouldWaitForGround = nextWaypoint.Action == Enum.PathWaypointAction.Jump
					if not shouldWaitForGround and this.CurrentPoint > 1 then
						local prevWaypoint = this.pointList[this.CurrentPoint - 1]

						local prevDir = currentWaypoint.Position - prevWaypoint.Position
						local currDir = nextWaypoint.Position - currentWaypoint.Position

						local prevDirXZ = Vector2.new(prevDir.x, prevDir.z).Unit
						local currDirXZ = Vector2.new(currDir.x, currDir.z).Unit

						local THRESHOLD_COS = 0.996 -- ~cos(5 degrees)
						shouldWaitForGround = prevDirXZ:Dot(currDirXZ) < THRESHOLD_COS
					end

					if shouldWaitForGround then
						this.Humanoid.FreeFalling:Wait()

						-- Give time to the humanoid's state to change
						-- Otherwise, the jump flag in Humanoid
						-- will be reset by the state change
						wait(0.1)
					end
				end

				-- Move to the next point
				this:MoveToNextWayPoint(currentWaypoint, nextWaypoint, nextWaypointIdx)
			end
		else
			this.PathFailed:Fire()
			this:Cleanup()
		end
	end

	function this:MoveToNextWayPoint(currentWaypoint, nextWaypoint, nextWaypointIdx)
		-- Build next destination plane
		-- (plane normal is perpendicular to the y plane and is from next waypoint towards current one (provided the two waypoints are not at the same location))
		-- (plane location is at next waypoint)
		this.CurrentWaypointPlaneNormal = currentWaypoint.Position - nextWaypoint.Position
		this.CurrentWaypointPlaneNormal = Vector3.new(this.CurrentWaypointPlaneNormal.X, 0, this.CurrentWaypointPlaneNormal.Z)
		if this.CurrentWaypointPlaneNormal.Magnitude > ALMOST_ZERO then
			this.CurrentWaypointPlaneNormal	= this.CurrentWaypointPlaneNormal.Unit
			this.CurrentWaypointPlaneDistance = this.CurrentWaypointPlaneNormal:Dot(nextWaypoint.Position)
		else
			-- Next waypoint is the same as current waypoint so no plane
			this.CurrentWaypointPlaneNormal	= ZERO_VECTOR3
			this.CurrentWaypointPlaneDistance = 0
		end

		-- Should we jump
		this.CurrentWaypointNeedsJump = nextWaypoint.Action == Enum.PathWaypointAction.Jump;

		-- Remember next waypoint position
		this.CurrentWaypointPosition = nextWaypoint.Position

		-- Move to next point
		this.CurrentPoint = nextWaypointIdx

		-- Finally reset Timeout
		this.Timeout = 0
	end

	function this:Start(overrideShowPath)
		if not this.AgentCanFollowPath then
			this.PathFailed:Fire()
			return
		end

		if this.Started then return end
		this.Started = true

		ClickToMoveDisplay.CancelFailureAnimation()

		if ShowPath then
			if overrideShowPath == nil or overrideShowPath then
				this.stopTraverseFunc, this.setPointFunc = ClickToMoveDisplay.CreatePathDisplay(this.pointList, this.OriginalTargetPoint)
			end
		end

		if #this.pointList > 0 then
			-- Determine the humanoid offset from the path's first point
			-- Offset of the first waypoint from the path's origin point
			this.HumanoidOffsetFromPath = Vector3.new(0, this.pointList[1].Position.Y - this.OriginPoint.Y, 0)

			-- As well as its current position and velocity
			this.CurrentHumanoidPosition = this.Humanoid.RootPart.Position + this.HumanoidOffsetFromPath
			this.CurrentHumanoidVelocity = this.Humanoid.RootPart.Velocity

			-- Connect to events
			this.SeatedConn = this.Humanoid.Seated:Connect(function(isSeated, seat) this:OnPathInterrupted() end)
			this.DiedConn = this.Humanoid.Died:Connect(function() this:OnPathInterrupted() end)
			this.TeleportedConn = this.Humanoid.RootPart:GetPropertyChangedSignal("CFrame"):Connect(function() this:OnPathInterrupted() end)

			-- Actually start
			this.CurrentPoint = 1 -- The first waypoint is always the start location. Skip it.
			this:OnPointReached(true) -- Move to first point
		else
			this.PathFailed:Fire()
			if this.stopTraverseFunc then
				this.stopTraverseFunc()
			end
		end
	end

	--We always raycast to the ground in the case that the user clicked a wall.
	local offsetPoint = this.TargetPoint + this.TargetSurfaceNormal*1.5
	local ray = Ray.new(offsetPoint, Vector3.new(0,-1,0)*50)
	local newHitPart, newHitPos = Workspace:FindPartOnRayWithIgnoreList(ray, getIgnoreList())
	if newHitPart then
		this.TargetPoint = newHitPos
	end
	this:ComputePath()

	return this
end
