I've seen many players reporting this problem but i can never seem to update my script to fix this problem. When NPCs are wandering, they always seem to stop and start moving, along with a short pause of animation.
some people say things about humanoid.MoveToFinished:Wait()
but i'm not sure if it has anything to do with the script i'm using.
Here is the script I am using, be warned it's long.
local players = Info.Players:GetPlayers() local closestCharacter, closestCharacterDistance for i=1, #players do local player = players[i] if player.Neutral or player.TeamColor ~= Settings.FriendlyTeam.Value then local character = player.Character if character ~= nil and character:FindFirstChild('Humanoid') ~= nil and character.Humanoid:IsA('Humanoid') then local distance = player:DistanceFromCharacter(Monster:GetCFrame().p) if distance < Monster:GetMaximumDetectionDistance() then if closestCharacter == nil then closestCharacter, closestCharacterDistance = character, distance else if closestCharacterDistance > distance then closestCharacter, closestCharacterDistance = character, distance end end end end end end if closestCharacter ~= nil then Mind.CurrentTargetHumanoid.Value = closestCharacter.Humanoid end end function Monster:TryRecomputePath() if Data.AutoRecompute or tick() - Data.LastRecomputePath > 1/Info.RecomputePathFrequency then Monster:RecomputePath() end end function Monster:GetTargetCFrame() local targetHumanoid = Mind.CurrentTargetHumanoid.Value if Monster:TargetIsValid() then return targetHumanoid.Torso.CFrame else return CFrame.new() end end function Monster:IsAlive() return Self.Humanoid.Health > 0 and Self.Humanoid.Torso ~= nil end function Monster:TargetIsValid() local targetHumanoid = Mind.CurrentTargetHumanoid.Value if targetHumanoid ~= nil and targetHumanoid:IsA 'Humanoid' and targetHumanoid.Torso ~= nil and targetHumanoid.Torso:IsA 'BasePart' then return true else return false end end function Monster:HasClearLineOfSight() -- Going to cast a ray to see if I can just see my target local myPos, targetPos = Monster:GetCFrame().p, Monster:GetTargetCFrame().p local hit, pos = Workspace:FindPartOnRayWithIgnoreList( Ray.new( myPos, targetPos - myPos ), { Self, Mind.CurrentTargetHumanoid.Value.Parent } ) if hit == nil then return true else return false end end function Monster:RecomputePath() if not Data.Recomputing then if Monster:IsAlive() and Monster:TargetIsValid() then if Monster:HasClearLineOfSight() then Data.AutoRecompute = true Data.PathCoords = { Monster:GetCFrame().p, Monster:GetTargetCFrame().p } Data.LastRecomputePath = tick() Data.CurrentNode = nil Data.CurrentNodeIndex = 2 -- Starts chasing the target without evaluating its current position else -- Do pathfinding since you can't walk straight Data.Recomputing = true -- Basically a debounce. Data.AutoRecompute = false local path = Info.PathfindingService:ComputeSmoothPathAsync( Monster:GetCFrame().p, Monster:GetTargetCFrame().p, 500 ) Data.PathCoords = path:GetPointCoordinates() Data.Recomputing = false Data.LastRecomputePath = tick() Data.CurrentNode = nil Data.CurrentNodeIndex = 1 end end end end function Monster:Update() Monster:ReevaluateTarget() Monster:SearchForTarget() Monster:TryRecomputePath() Monster:TravelPath() end function Monster:TravelPath() local closest, closestDistance, closestIndex local myPosition = Monster:GetCFrame().p local skipCurrentNode = Data.CurrentNode ~= nil and (Data.CurrentNode - myPosition).magnitude < 3 for i=Data.CurrentNodeIndex, #Data.PathCoords do local coord = Data.PathCoords[i] if not (skipCurrentNode and coord == Data.CurrentNode) then local distance = (coord - myPosition).magnitude if closest == nil then closest, closestDistance, closestIndex = coord, distance, i else if distance < closestDistance then closest, closestDistance, closestIndex = coord, distance, i else break end end end end -- if closest ~= nil then Data.CurrentNode = closest Data.CurrentNodeIndex = closestIndex local humanoid = Self:FindFirstChild 'Humanoid' if humanoid ~= nil and humanoid:IsA'Humanoid' then humanoid:MoveTo(closest) end if Monster:IsAlive() and Monster:TargetIsValid() then Monster:TryJumpCheck() Monster:TryAttack() end if closestIndex == #Data.PathCoords then -- Reached the end of the path, force a new check Data.AutoRecompute = true end end end
Hope there is something that can be done about this. Also, sorry for the long script again.
Just type this
local h = script.Parent.Humanoid local torso = script.Parent.UpperTorso --Torso if Mob is r6 UpperTorso if Mob is r15 local spawnCF = torso.CFrame function findPlayer() for _,v in next, game.Players:GetPlayers() do if v.Character then local char = v.Character if char:FindFirstChild("Humanoid") and char:FindFirstChild("UpperTorso") then --Torso if Player is r6 UpperTorso if Player is r15 local ptorso = char.UpperTorso --Torso if Player is r6 UpperTorso if Player is r15 if (ptorso.Position - torso.Position).magnitude <= 20 then return v end end end end return nil end while wait() do local player = findPlayer() if player ~= nil then h.WalkToPoint = player.Character.UpperTorso.Position --Torso if Player is r6 UpperTorso if Player is r15 else h.WalkToPoint = spawnCF.p end end