NPC not moving completely to Raycast Result position

I want to make a zombie NPC move towards a position it receives from a Raycast Result when it gets tagged in collection service. The raycast starts at the HumanoidRootPart LookVector and it gets the correct position each time.

The problem is that the NPC never moves all the way to the goal position and it falls short by a lot of studs and I’m not sure why. Here is a picture of what I mean:


There is a result position and end position for the NPC in the output.
This is also the code I use for it.
Function:

function attackPosition(obj)
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Blacklist
	params.FilterDescendantsInstances = {workspace.CloneFolder}
	params.IgnoreWater = true
	local rayResult = workspace:Raycast(obj.HumanoidRootPart.Position, obj.HumanoidRootPart.CFrame.LookVector*600, params)
	wait(1)
	if rayResult then
		if rayResult.Instance:GetFullName() == "MainWall" or "Walls" then
			print("Result position: ",rayResult.Position)
			obj.Humanoid:MoveTo(rayResult.Position)
			obj.Humanoid.MoveToFinished:Wait()
			print("End position: ",obj.HumanoidRootPart.Position)
		end
	end
end

Humanoids have a MoveTo timeout of 8 seconds, is your Zombie taking longer than 8 seconds to reach it’s destination?

If so, when MoveToFinished is fired, try doing a magnitude check between the NPC’s position and the end position, if it’s not close enough attempt to move to it again and repeat this until if moves to the destination.

Edit: Judging from the output, this seems to be the case, as the end position is printed 8 seconds after the result. I believe this may be your answer.

Adding to what @FlabbyBoiii said, Roblox made a code sample for this which makes live a lot easier you can find it here, I did edit the code for performance issues.

local function moveTo(humanoid, targetPoint, andThen)
	local targetReached = false
 
	-- listen for the humanoid reaching its target
	local connection
	connection = humanoid.MoveToFinished:Connect(function(reached)
		targetReached = true
		connection:Disconnect()
		connection = nil
		if andThen then
			andThen()
		end
	end)
 
	-- start walking
	humanoid:MoveTo(targetPoint)
 
	-- execute on a new thread so as to not yield function; instead of spawn() we will use 
    --coroutine.wrap()() as spawn() has a small delay.
	coroutine.wrap(function()
		while not targetReached do
			-- does the humanoid still exist?
			if not (humanoid and humanoid.Parent) then
				break
			end
			-- has the target changed?
			if humanoid.WalkToPoint ~= targetPoint then
				break
			end
			-- refresh the timeout
			humanoid:MoveTo(targetPoint)
			wait(6)
		end
		
		-- disconnect the connection if it is still connected
		if connection then
			connection:Disconnect()
			connection = nil
		end
	end)()
end
1 Like

Ok thanks I’ll give this a try.