My NPC goes to my old position and then computes a new path to my position ater it reached the last waypoint.
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local PathfindingService = game:GetService("PathfindingService")
local mom = script.Parent
local humanoid = mom:WaitForChild("Humanoid")
local torso = mom:WaitForChild("Torso")
humanoid.WalkSpeed = 20
local startingPart = Workspace:WaitForChild("StartingPart")
local roomPart = Workspace:WaitForChild("RoomPart")
local stopPart = Workspace.stopPart
local stopMoving = false
local blacklistedPlayers = {}
local nearStartingPart = false
local path = nil
local waypoints = nil
local visualize = true
local folder = nil
if visualize then
folder = Instance.new("Folder")
folder.Name = "Waypoints"
folder.Parent = workspace
end
local function isPlayerBlacklisted(player)
for _, blacklistedPlayer in ipairs(blacklistedPlayers) do
if player == blacklistedPlayer then
return true
end
end
return false
end
local function addToBlacklist(player)
table.insert(blacklistedPlayers, player)
end
local function removeFromBlacklist(player)
for i, blacklistedPlayer in ipairs(blacklistedPlayers) do
if player == blacklistedPlayer then
table.remove(blacklistedPlayers, i)
break
end
end
end
local function moveMom(direction)
if not stopMoving then
humanoid:Move(direction)
else
humanoid:Move(Vector3.new())
end
end
local function goToPart(part)
print("Mom is going to", part.Name)
path = nil
if visualize then
for _, child in ipairs(folder:GetChildren()) do
child:Destroy()
end
end
path = PathfindingService:CreatePath({
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = true,
AgentJumpHeight = 10,
})
path:ComputeAsync(torso.Position, part.Position)
waypoints = path:GetWaypoints()
if visualize then
for i, waypoint in ipairs(waypoints) do
local part = Instance.new("Part")
part.Shape = Enum.PartType.Ball
part.Color = Color3.fromRGB(255, 90, 61)
part.Material = Enum.Material.Neon
part.CFrame = CFrame.new(waypoint.Position)
part.Name = i
part.Anchored = true
part.Size = Vector3.new(1, 1, 1)
part.CanCollide = false
part.Parent = folder
end
end
while true do
for i, waypoint in ipairs(waypoints) do
if stopMoving or not path:IsValid() then
return
end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
end
end
local function nearStopPart()
local momTorso = mom:FindFirstChild("Torso")
if momTorso then
return (momTorso.Position - stopPart.Position).Magnitude < 5
end
return false
end
local function shouldStopMoving(catchPlayerFunction)
for _, playerToCheck in ipairs(Players:GetPlayers()) do
if playerToCheck.Character and playerToCheck.Character:FindFirstChild("Humanoid") and not playerToCheck.Character:FindFirstChild("Humanoid").SeatPart then
print(playerToCheck.Name, "unsat while going to StartingPart. Mom will turn back.")
removeFromBlacklist(playerToCheck)
humanoid:MoveTo(torso.Position)
stopMoving = true
local anyAlivePlayers = false
for _, player in ipairs(Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("Humanoid") and player.Character:FindFirstChild("Humanoid").Health > 0 then
anyAlivePlayers = true
if player.Character:FindFirstChild("Humanoid").SeatPart then
print(player.Name, "is sitting at RoomPart. Mom will not kill.")
else
print(player.Name, "unsat at RoomPart. Mom will kill.")
catchPlayerFunction(player)
end
end
end
if anyAlivePlayers and not nearStartingPart and not nearStopPart() then
print("Mom is going to RoomPart")
goToPart(roomPart)
wait(5)
print("Finished waiting at RoomPart.")
end
local waitStartTime = tick()
while stopMoving do
wait(0.1)
if tick() - waitStartTime > 5 then
print("Timeout: Mom waiting to stop moving.")
break
end
end
return true
end
end
return false
end
local function updatePath(player)
-- Update the path to the player's current position
if not path or not path:IsA("Path") then
path = PathfindingService:CreatePath({
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = true,
AgentJumpHeight = 10,
})
end
local playerRootPart = player.Character:FindFirstChild("HumanoidRootPart")
if playerRootPart then
local playerPosition = playerRootPart.Position
local momPosition = torso.Position
path:ComputeAsync(momPosition, playerPosition)
waypoints = path:GetWaypoints()
if visualize then
for _, waypoint in ipairs(waypoints) do
local part = Instance.new("Part")
part.Shape = Enum.PartType.Ball
part.Color = Color3.fromRGB(98, 87, 255)
part.Material = Enum.Material.Neon
part.CFrame = CFrame.new(waypoint.Position)
part.Name = "Waypoint"
part.Anchored = true
part.Size = Vector3.new(1, 1, 1)
part.CanCollide = false
part.Parent = folder
end
end
end
end
local function catchPlayer(player)
print("Mom is dynamically checking if player is sitting before chasing", player.Name)
while player.Character and player.Character:FindFirstChild("Humanoid") and player.Character.Humanoid.Health > 0 do
if player.Character:FindFirstChild("Humanoid").SeatPart then
print(player.Name, "is sitting. Mom will not chase.")
break
end
updatePath(player)
for _, waypoint in ipairs(waypoints) do
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
local distanceToPlayer = (torso.Position - player.Character:WaitForChild("HumanoidRootPart").Position).Magnitude
if distanceToPlayer < 1 then
print("Touching player:", player.Name)
if not isPlayerBlacklisted(player) then
if player.Character:FindFirstChild("Humanoid").Health > 0 then
player.Character.Humanoid.Health = 0
print("Player killed:", player.Name)
addToBlacklist(player)
print(player.Name, "added to the blacklist.")
end
end
break
end
wait(0.1)
end
end
while true do
wait(math.random(5, 10))
local nonSittingPlayers = {}
for _, player in ipairs(Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("Humanoid") and not player.Character:FindFirstChild("Humanoid").SeatPart then
if not isPlayerBlacklisted(player) then
table.insert(nonSittingPlayers, player)
end
end
end
if #nonSittingPlayers > 0 then
print("Non-sitting players detected. Trying to catch them.")
for _, player in ipairs(nonSittingPlayers) do
catchPlayer(player)
end
end
local anyAlivePlayers = false
for _, player in ipairs(Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("Humanoid") and player.Character:FindFirstChild("Humanoid").Health > 0 then
anyAlivePlayers = true
end
end
if not anyAlivePlayers then
print("No living players found, going to StartingPart and ending script.")
goToPart(startingPart)
break
end
if not nearStartingPart and not nearStopPart() then
goToPart(roomPart)
end
local sittingPlayers = false
for _, player in ipairs(Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("Humanoid") and player.Character.Humanoid.SeatPart then
sittingPlayers = true
break
end
end
if nearStopPart() then
print("Mom is near stopPart, stopping all functions related to going to RoomPart.")
else
if sittingPlayers then
print("Waiting at RoomPart for 5 seconds.")
local startTime = tick()
while tick() - startTime < 5 do
local allSitting = true
for _, player in ipairs(Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("Humanoid") and not player.Character:FindFirstChild("Humanoid").SeatPart then
allSitting = false
break
end
end
if not allSitting or shouldStopMoving(catchPlayer) then
print("Not all players are sitting or someone unsat. Aborting wait at RoomPart.")
break
end
print(tick() - startTime)
wait(0.1)
end
local allSitting = true
for _, player in ipairs(Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("Humanoid") and not player.Character:FindFirstChild("Humanoid").SeatPart then
allSitting = false
break
end
end
if allSitting then
print("All players are still sitting. Going to StartingPart.")
goToPart(startingPart)
while torso.Position ~= startingPart.Position do
wait(0.1)
if shouldStopMoving(catchPlayer) then
break
end
end
if torso.Position == startingPart.Position then
print("Mom reached StartingPart. Ending script.")
break
end
else
print("Not all players are sitting. Skipping going to StartingPart.")
end
else
print("No sitting players. Skipping wait at RoomPart.")
end
end
for _, player in ipairs(Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("Humanoid") and not player.Character:FindFirstChild("Humanoid").SeatPart then
print(player.Name, "unsat at RoomPart. Mom will kill.")
catchPlayer(player)
end
end
print("Finished waiting at RoomPart.")
stopMoving = false
local originalDestination = startingPart.Position
while humanoid.WalkToPoint ~= Vector3.new() and not nearStartingPart and not nearStopPart() do
wait(0.1)
if shouldStopMoving(catchPlayer) then
break
end
end
if not stopMoving and not nearStartingPart and not nearStopPart() then
goToPart(startingPart)
end
end
Video: https://vimeo.com/888253706?share=copy
I tried visualising waypoints and adding checks but I still cant figure it out. I also tried removing: humanoid.MoveToFinished:Wait() but that breaks the script.