You might of seen my posts on my piggy thing but I have switched to pathFinding, not Humanoid:MoveTo() (so my piggy jumps).
But instead of chasing the player + jumping when it needs to, it instead has different ideas.
The idea of dying.
Like, jumping off the edge of the map. It only has 1 waypoint which is when it starts moving. It does not chase the player.
Here is the ServerScript in the NPC:
local npcHRP = script.Parent.HumanoidRootPart
local PathFindingServ = game:GetService("PathfindingService")
local npcH = script.Parent.Humanoid
local npcT = script.Parent.Torso
local function GetNearestPlayer(minimumDistance)
local closestMagnitude = minimumDistance or math.huge
--minimumDistance is a number in studs
local closestPlayer
for i,v in next, game.Players:GetPlayers() do
local Character = v.Character
if (Character) then
local humanoid = Character.Humanoid
local HRP = Character.HumanoidRootPart
if (humanoid.Health > 0) then
local mag = (npcHRP.Position - HRP.Position).Magnitude
if (mag <= closestMagnitude) then
closestPlayer = v
closestMagnitude = mag
end
end
end
end
return closestPlayer
end
while wait() do
local nearPlr = GetNearestPlayer(70)
pcall(function()
local path = PathFindingServ:CreatePath()
path:ComputeAsync(npcHRP.Position, nearPlr.Character.HumanoidRootPart.Position)
local waypoints = path:GetWaypoints()
for _, wp in pairs(waypoints) do
if wp.Action == Enum.PathWaypointAction.Jump then
script.Parent.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping) -- If I put a brick in front of the NPC, it doesn't jump.
end
print(wp.Action)
script.Parent.Humanoid:Move(wp.Position)
script.Parent.Humanoid.MoveToFinished:Wait()
end
end)
end
NOTE: If I put a brick in front of the NPC, it doesn’t jump.
You shouldn’t do the pathfinding stuff in a pcall(). Only use pcall() for errors that you can’t control yourself, like datastore or HttpService. Using pcall() for random things mask errors, and seeing the errors are helpful in debugging and finding issues with your code.
Also, you only need to create one path. So you can remove it from the while wait() do and put it at the top of the script instead. Calling :ComputeAsync() will always automatically recompute the path, so it’s a waste to create a new path each time.
Also, once you run :ComputeAsync(), make sure path.Status == Enum.PathStatus.Success. If it doesn’t equal that, then re-compute the path so the NPC knows where to go. You also don’t have any kind of measure to handle when a path gets blocked, so I would recommend adding that. Listen to when the path gets blocked and recompute the path if the blocked waypoint wasn’t passed by the NPC.
local npcHRP = script.Parent.HumanoidRootPart
local PathFindingServ = game:GetService("PathfindingService")
local npcH = script.Parent.Humanoid
local npcT = script.Parent.Torso
local function GetNearestPlayer(minimumDistance)
local closestMagnitude = minimumDistance or math.huge
--minimumDistance is a number in studs
local closestPlayer
for i,v in next, game.Players:GetPlayers() do
local Character = v.Character
if (Character) then
local humanoid = Character.Humanoid
local HRP = Character.HumanoidRootPart
if (humanoid.Health > 0) then
local mag = (npcHRP.Position - HRP.Position).Magnitude
if (mag <= closestMagnitude) then
closestPlayer = v
closestMagnitude = mag
end
end
end
end
return closestPlayer
end
local closestPlayer = GetNearestPlayer(70)
local newThing = coroutine.create(function()
while wait(3) do
closestPlayer = GetNearestPlayer(70)
end
end)
local newPath = coroutine.create(function(path)
while wait(3) do
path:ComputeAsync(npcT.Position, closestPlayer:WaitForChild("Character").HumanoidRootPart.Position)
end
end)
coroutine.resume(newThing)
local path = PathFindingServ:CreatePath()
coroutine.resume(newPath(path))
local waypoints = path:GetWaypoints()
for _, wp in pairs(waypoints) do
if wp.Action == Enum.PathWaypointAction.Jump then
script.Parent.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
print(wp.Action)
script.Parent.Humanoid:Move(wp.Position)
script.Parent.Humanoid.MoveToFinished:Wait()
end
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")
local path = PathfindingService:CreatePath()
local function getClosestPlayer(position)
local players = Players:GetPlayers()
local closestDistance, closestPosition, closestPlayer = math.huge, nil, nil
for i, player in ipairs(players) do
if not player.Character then continue end
local playerPosition = player.Character:GetPrimaryPartCFrame()
local distance = (playerPosition.Position - position).Magnitude
if distance < closestDistance then
closestDistance = distance
closestPosition = playerPosition.Position
closestPlayer = player
end
end
return closestPlayer, closestPosition
end
while wait(<arbitrary number here>) do
local currentPosition = <NPCs Vector3 pos here>
local closestPlayer, closestPosition = getClosestPlayercurrentPosition)
path:ComputeAsync(currentPosition, closestPosition)
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
local currentWaypoint = 0
path.Blocked:Connect(function(index)
if index >= currentWaypoint then
-- recompute path
end
end)
else
-- recompute path
end
end
I litteraly don’t understand anything right now.
Here is the new script:
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")
local path = PathfindingService:CreatePath()
function getClosestPlayer(position)
local players = Players:GetPlayers()
local closestDistance, closestPosition, closestPlayer = math.huge, nil, nil
for i, player in ipairs(players) do
if not player.Character then continue end
local playerPosition = player.Character:GetPrimaryPartCFrame()
local distance = (playerPosition.Position - position).Magnitude
if distance < closestDistance then
closestDistance = distance
closestPosition = playerPosition.Position
closestPlayer = player
end
end
return closestPlayer, closestPosition
end
while wait(3) do
local currentPosition = script.Parent.Torso.Position
local closestPlayer, closestPosition = getClosestPlayer(currentPosition)
path:ComputeAsync(currentPosition, closestPosition)
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
local currentWaypoint = 0
path.Blocked:Connect(function(index)
if index >= currentWaypoint then
path:ComputeAsync(currentPosition, closestPosition)
end
end)
else
path:ComputeAsync(currentPosition, closestPosition)
end
end