Wait but how would I make it keep making a path for the NPC to follow?
Is it another while wait(3) do?
Does this work?
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
Nope it doesn’t.
line 47: attempt to call a thread value
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
How would I re-compute it? Would I just do createpath all over again?
btw you’re using coroutines incorrectly. The proper way is coroutine.resume(coro, ...args)
.
local thread = coroutine.create(function(...)
return select("#", ...)
end)
local argCount = coroutine.resume(thread, 1, 2, 3)
print(argCount) --> 3
No, if you just remove the local
from in front of the function, you can call the function inside itself.
I am not an advanced scripter so I don’t understand what this means.
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
How would I change the distance?
It’s called recursion:
function thing()
thing() --> you can call the function from inside itself
end
you have to be careful when you do it though because in the above code block it creates an infinite loop which will result in a stack overflow.
I give up on this. I don’t understand a single THING.
Oh and what’s better is I have just lost my whole script. GREAT.
Basically you want to move the code inside the while loop into a seperate function, then call that function inside the while loop.
See this is why my bio tells you more about my scripting job.
I quit making games. Thanks for helping. Bye.
Mutiple versions of your code are still posted on this thread so you can re-copy that if you want to attempt working on pathfinding again.
Sorry for wasting your o-so precious time
Ok maybe I want to work on it again but can we do it on this post: How would I make a NPC jump when using :MoveTo() - #17 by graviiity
Since I have a new script.