:MoveTo() Isn't Working Smoothly And Stops When Part Changed It's Position

Thanks. Have A Good Day. Bye! I Will Reply This Again Tomorrow.

Your code (Modified works good). I ran into small lag, nothing major, must be the for loop or getTarget(), I’m not sure to be honest with you. This is what I got from your code (modified):

:exclamation:Edit: Could not Upload the Video(tried multiple times)

And this is the code:

modified code
local humanoid = script.Parent:WaitForChild("Humanoid")
local humanoidrootpart = script.Parent:WaitForChild("HumanoidRootPart")
local MoveAround = script.Parent:WaitForChild("movee") -- walk to Parts in Character(I did this as I every npc has their own, though there is a better way now)

function findNearestPlayer(Position)
	task.wait(0.3)
	local List = game.Workspace:GetChildren()
	local Torso = nil
	local Distance = 30 --  Range to search for Targets
	local Temp = nil
	local Human = nil
	local Temp2 = nil
	for x = 1, #List do
		Temp2 = List[x]
		if (Temp2.className == "Model") and (Temp2 ~= script.Parent) then
			Temp = Temp2:findFirstChild("HumanoidRootPart")
			Human = Temp2:findFirstChild("Humanoid")
			if (Temp ~= nil) and (Human ~= nil) and (Human.Health > 0) then
				if (Temp.Position - Position).magnitude < Distance then
					Torso = Temp
					Distance = (Temp.Position - Position).magnitude 
				end
			end
		end
	end
	return Torso
end

local function Attack(target)
	local distance = (humanoidrootpart.Position - target.Position).Magnitude

	if target.Parent.Humanoid.Health == 0 then return end

	if distance > 2 then
		humanoid.WalkSpeed = 16

		humanoid:MoveTo(target.Position, target)
	else
		--game:GetService('ReplicatedStorage').Events["JumpScare Events"]["Monster-K Event"]:FireClient(players:GetPlayerFromCharacter(target))

		humanoid.WalkSpeed = 0
		humanoid.JumpPower = 0

		--MonsterKAnimationLoad:Play()

		target.Parent.Humanoid.Health = 0

		--MonsterKAnimationLoad.Stopped:Wait()
		task.wait(2)
		humanoid.WalkSpeed = 16
		humanoid.JumpPower = 50
	end
end

local function MoveTo()
	--for index, waypoint in pairs(path:GetWaypoints()) do
		local target = findNearestPlayer(humanoidrootpart.Position)
		if target then
			Attack(target)
		else
			if humanoid.WalkSpeed == 24 then humanoid.WalkSpeed = 16 end
			local part = MoveAround:GetChildren()[math.random(1,#MoveAround:GetChildren())]
			humanoid:MoveTo(part.Position)
			humanoid.MoveToFinished:Wait()
		end
	--end
end

--[[local function patrol()
	local waypoints = game:GetService('Workspace').Monster.Positions:GetChildren()
	local random = math.random(1, #waypoints)

	MoveTo(waypoints[random])
end]]

while wait(0.5) do	
	MoveTo()
end
1 Like

I Used PathService because the A.I can stuck to the walls.

But in modified code it uses :MoveTo() which can get stuck by walls or something like these

I can only assume it’s the wait at 0.5 . Other than that, I found this YouTubeVideo with this Code:

Code
local pathfinding = game.PathfindingService
local players = game.Players
local runService = game["Run Service"]

local enemy = script.Parent
local humanoid = enemy:WaitForChild("Humanoid")
enemy.PrimaryPart:SetNetworkOwner(nil)

local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection

local walkSpeed = 17
local sprintSpeed = 20
local damage = 0
local maxDistance = 100

local function getPath(destination)
	local path = pathfinding:CreatePath({
		AgentHeight = 6;
		AgentRadius = 3;
		AgentCanJump = false;
		AgentCanClimb = false;
		
		Costs = {
			Water = 100;
			DangerZone = math.huge
		}
	})
	
	path:ComputeAsync(enemy.HumanoidRootPart.Position, destination.Position)
	
	return path
end

local function findTarget()
	local nearestTarget
	maxDistance = enemy:GetAttribute("MaxDistance")
	
	for index, player in pairs(players:GetPlayers()) do
		if player.Character then
			local target = player.Character
			local distance = (enemy.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
			
			if distance < maxDistance then
				nearestTarget = target
				maxDistance = distance
			end
		end
	end
	
	return nearestTarget
end

local function capture(target)
	local distance = (enemy.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
	
	if distance > 3 then
		humanoid:MoveTo(target.HumanoidRootPart.Position)
	else
                -- Jumpscare Event
		--target.Humanoid:TakeDamage(damage)
	end
end

local function walkTo(destination)
	local path = getPath(destination)
	
	if path.Status == Enum.PathStatus.Success then
		for index, waypoint in pairs(path:GetWaypoints()) do
			local target = findTarget()
			
			if target then
				capture(target)
				enemy.Humanoid.WalkSpeed = sprintSpeed
				break
			else
				enemy.Humanoid.WalkSpeed = walkSpeed
				humanoid:MoveTo(waypoint.Position)
				humanoid.MoveToFinished:Wait()
			end
		end
	else
		humanoid:MoveTo(destination.Position - (enemy.HumanoidRootPart.CFrame.LookVector * 10))
	end
end

local function patrol()
	local waypoints = workspace["AI Waypoints"]:GetChildren()
	local randomWaypoint = math.random(1, #waypoints)
	walkTo(waypoints[randomWaypoint])
end

while wait(0.01) do
	patrol()
end

Try something like this …

snip

for i,waypoint in ipairs(waypoints)do
		local distance=(waypoint.Position-PrimaryPart.Position).Magnitude
		local duration=(distance/(Humanoid.WalkSpeed*1.033)) --⏳--adjust
		humanoid:MoveTo(waypoint.Position)

Next Position has a heartbeat:Wait() to get to this again.

I Used :MoveTo() for attack and Used PathService For Patrolling. Here Is The Full Code :

local pathfindingservice = game:GetService('PathfindingService')

local players = game:GetService('Players')

local monsterchar = script.Parent.Parent
local humanoid = monsterchar.Humanoid
local humanoidrootpart = monsterchar.HumanoidRootPart

local MonsterKAnimation = script.Parent.Animations["Monster-K Animation"]

local MonsterKAnimationLoad = monsterchar.Humanoid.Animator:LoadAnimation(MonsterKAnimation)

monsterchar.PrimaryPart:SetNetworkOwner(nil)

local function getTarget()
	local players = game:GetService('Players'):GetPlayers()
	local bestTarget

	local maxdistance = 40

	for index, player in pairs(players) do
		if player.Character then
			local target = player.Character

			local distance = (humanoidrootpart.Position - target.PrimaryPart.Position).Magnitude

			if distance <= maxdistance then
				bestTarget = target

				maxdistance = distance
			end
		end
	end

	return bestTarget
end

local function getPath(destination)
	local path = pathfindingservice:CreatePath({
		AgentCanJump = false
	})

	path:ComputeAsync(humanoidrootpart.Position, destination.Position)

	return path
end

local function Attack(target)
	local distance = (humanoidrootpart.Position - target.PrimaryPart.Position).Magnitude
	
	if target.Humanoid.Health == 0 then return end
	
	if distance > 2 then
		humanoid.WalkSpeed = 24
		
		humanoid:MoveTo(target.PrimaryPart.Position, target.PrimaryPart)
	else
		game:GetService('ReplicatedStorage').Events["JumpScare Events"]["Monster-K Event"]:FireClient(players:GetPlayerFromCharacter(target))
		
		humanoidrootpart.Anchored = true
		
		MonsterKAnimationLoad:Play()
		
		target.Humanoid.Health = 0
		
		MonsterKAnimationLoad.Stopped:Wait()
		
		humanoidrootpart.Anchored = false
		
		humanoid.WalkSpeed = 16
	end
end

local function MoveTo(destination)
	local path = getPath(destination)
	
	for index, waypoint in pairs(path:GetWaypoints()) do
		local target = getTarget()
		if target then
			Attack(target)
			break
		else
			if humanoid.WalkSpeed == 24 then humanoid.WalkSpeed = 16 end
			
			humanoid:MoveTo(waypoint.Position)
			humanoid.MoveToFinished:Wait()
		end
	end
end

local function patrol()
	local waypoints = game:GetService('Workspace').Monster.Positions:GetChildren()
	local random = math.random(1, #waypoints)

	MoveTo(waypoints[random])
end

while wait(0.5) do	
	patrol()
end

I think i am gonna do this tomorrow again because of my timezone (GMT+4). Maybe I Look At 01:00 or smth like that ( In My TimeZone ).

Back After 3 Days. I Had Other Things To Do. And No Fixes :crying_cat_face:

I did like this:

while wait() do
	patrol()
end

Now it is so laggy

I really don’t wanna give up but i think i am gonna…

Well it’s because it reached it’s position?

Yeah that is the problem. When it reaches position because of patrolling it waits like 0.5 second and then it follows you back. But when i do it while true do it just doesn’t waits for it reaches the position. it just attacks repeatedly and not waiting for it to end and it makes it laggy. And i don’t know how to make it to waits for :MoveTo() finished while ATTACK is enabled. When i just do while true do MoveToFinished:Wait() it errors because when it doesn’t attack it doesn’t moveto somewhere and it stops. ( Sorry if grammar mistakes )

How to detect if humanoid moveto is moving. I used movedirection but i think i did use it wrong or it doesn’t work.

Tried this code :

local pathfindingservice = game:GetService('PathfindingService')

local players = game:GetService('Players')

local monsterchar = script.Parent.Parent
local humanoid = monsterchar.Humanoid
local humanoidrootpart = monsterchar.HumanoidRootPart

local MonsterKAnimation = script.Parent.Animations["Monster-K Animation"]

local MonsterKAnimationLoad = monsterchar.Humanoid.Animator:LoadAnimation(MonsterKAnimation)

monsterchar.PrimaryPart:SetNetworkOwner(nil)

local function getTarget()
	local players = game:GetService('Players'):GetPlayers()
	local bestTarget

	local maxdistance = 40

	for index, player in pairs(players) do
		if player.Character then
			local target = player.Character

			local distance = (humanoidrootpart.Position - target.PrimaryPart.Position).Magnitude

			if distance <= maxdistance then
				bestTarget = target

				maxdistance = distance
			end
		end
	end

	return bestTarget
end

local function getPath(destination)
	local path = pathfindingservice:CreatePath({
		AgentCanJump = false
	})

	path:ComputeAsync(humanoidrootpart.Position, destination.Position)

	return path
end

local function Attack(target)
	local distance = (humanoidrootpart.Position - target.PrimaryPart.Position).Magnitude
	
	if distance > 2.5 then
		humanoid.WalkSpeed = 24
		
		humanoid:MoveTo(target.PrimaryPart.Position, target.PrimaryPart)
		humanoid.MoveToFinished:Wait()
	else		
		game:GetService('ReplicatedStorage').Events["JumpScare Events"]["Monster-K Event"]:FireClient(players:GetPlayerFromCharacter(target))
		
		humanoidrootpart.Anchored = true
		
		MonsterKAnimationLoad:Play()
		
		target.Humanoid.Health = 0
		
		MonsterKAnimationLoad.Stopped:Wait()
		
		humanoidrootpart.Anchored = false
		
		humanoid.WalkSpeed = 16
	end
end

local function MoveTo(destination)
	local path = getPath(destination)
	
	for index, waypoint in pairs(path:GetWaypoints()) do
		local target = getTarget()
		if target and target.Humanoid.Health > 0 then
			Attack(target)
			break
		else
			if humanoid.WalkSpeed == 24 then humanoid.WalkSpeed = 16 end
			
			humanoid:MoveTo(waypoint.Position)
			humanoid.MoveToFinished:Wait()
		end
	end
end

local function patrol()
	local waypoints = game:GetService('Workspace').Monster.Positions:GetChildren()
	local random = math.random(1, #waypoints)
	
	MoveTo(waypoints[random])
end

while true do
	patrol()
end

but at the end the studio crashed ( the client also crashes )

I’m not sure if this will help, but you can try adding a bit of forward distance so that the NPC runs past the player, thereby not stopping at the player’s last point. However, I must warn you that this approach might either help or make the NPC’s behavior a bit strange.

Position = HumanoidRootPart.Position + HumanoidRootPart.CFrame.LookVector * 2

It will increase the distance where the NPC needs to go by 2 units in the direction the player is facing

It works good now but it is so much laggy and crashes

If you wanna see how it acts i can add you to tester

Feel free to add it if you want; I’ll check it later. I haven’t fully grasped how to use PathfindingService yet.

no i am using it with :MoveTo() only patrolling is pathfinding.

and here is the link. : [Alpha]