How do I make npc using simple path to face moving character while moving. I tried every method it all glitches out. All done on server.
you can change the cframe every frame, or use align orientation
How would I make the NPC rotate to a specific orientation (or the rotation the targetpart is facing) after movetofinished?
This module is broken I believe, it either just crashes studio or just gives me an error whenever I attempt to use it, it worked completely fine like a week or two ago.
User error more than likely, show code
I’m not showing the entire script but I will show the parts that use the module, there is more stuff but that mainly just handles damaging and detecting when the player can be attacked. Also, it won’t crash when I remove everything involving the module, so its not the other stuff crashing it.
local simplePath = require(game.ServerStorage:WaitForChild("SimplePath"))
local SCP = script.Parent
local path = simplePath.new(SCP)
local function findTarget(pos) -- forgot to include at first, had to add it into this message rq.
local list = game.Workspace:GetChildren()
local root = nil
local dist = 500
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) and not temp2:FindFirstChild("Ignore") then
temp = temp2:findFirstChild("HumanoidRootPart")
human = temp2:FindFirstChildOfClass("Humanoid")
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
if (temp.Position - pos).magnitude < dist then
root = temp
dist = (temp.Position - pos).magnitude
end
end
end
end
return root
end
task.spawn(function()
while task.wait() do
local target = findTarget(SCP.PrimaryPart.Position) -- using my own find plr function instead of simplepath's due to me having to check if its a valid target and not another SCP.
if target then
path:Run(target)
end
end
end)
I just tested the NPC again today and it works completely fine again, I don’t know why it was bugged yesterday causing the crash, strange…
Hello! I’m lazy but at the beginning of the topic you left a guide on how to implement this module, but I saw that the module has several updates ; Should I use the guide you left at the beginning? I really need to implement it in my game.
How does this module handle multiple NPCs running at once? Haven’t tried it out yet but I plan to make a wave based enemy system with a multiple enemies (5 - 25) and I was curious how this module will hold up when it comes to performance.
If you really need to implement it, don’t be lazy. Read the documentation
Im having problems with multiple enemies using pathfinding, they’re moving towards the closest player but they keep walking back and then move a little towards the player and repeating. I’m writing it exactly like the documentation I don’t understand why its doing this. Btw it only does this when multiple enemies are spawned in but if there is only one it works perfectly.
--Import the module so you can start using it
local ServerStorage = game:GetService("ServerStorage")
local SimplePath = require(ServerStorage.SimplePath)
--Define npc
local dummy = script.Parent
--Create a new Path using the Dummy
local Path = SimplePath.new(dummy)
--Helps to visualize the path
Path.Visualize = false
local isDestroyed = false
local maxDistance = 100000
function getClosestPlayer()
local nearestPlayer, nearestDistance
for _, player in pairs(game.Players:GetPlayers()) do
local character = player.Character
local distance = player:DistanceFromCharacter(dummy.HumanoidRootPart.Position)
if not character or
distance > maxDistance or
(nearestDistance and distance >= nearestDistance)
then
continue
end
nearestDistance = distance
nearestPlayer = player
end
if nearestPlayer.Character.HumanoidRootPart then
return nearestPlayer.Character.HumanoidRootPart
end
end
local run = script:WaitForChild("run")
local humanoid = dummy:WaitForChild("Humanoid")
local runAnimation = humanoid:LoadAnimation(run)
while true do
Path:Run(getClosestPlayer())
end
Having an issue where when the Humanoid dies, the rig has a chance to disappear. I have added a ragdoll on death but when removing it still does the same thing.
Has worked well for my game with bot waves, but your surrounding logic needs to minimize how often it tries to recalc routes if things get stuck, etc
Edit: I should note that I manage all the npc from a single script and run their individual logic on a coroutine thread
I manage it from a single script as well. Do you mind sharing how I could optimize recalculating paths when it comes to enemies in waves, as that’s what I’m going for as well?
Keep in my mind, the NPC’s only disappear rarely when normally walking, but almost 80% of the time on death. Not sure if this has to do anything with recalc routes but I’m fairly new to this module.
function class:Start()
local rig : Model = self.Rig
local humanoid : Humanoid = self.Rig.Humanoid
local radius = 20
local player = nil
local isFollowing = false
local followRange = 80 -- Adjust the follow range as needed
local nearestPlayer
local Path = simplePath.new(rig)
Path.Visualize = true
self.Walk:Play()
humanoid.StateChanged:Connect(function(old, new)
if new == Enum.HumanoidStateType.Dead then
self.Idle:Stop()
self.Walk:Stop()
Path:Destroy()
end
end)
local function followPlayer()
if rig.Humanoid.Health > 0 then
nearestPlayer = findNearestPlayer(followRange, rig.PrimaryPart)
if nearestPlayer then
isFollowing = true
--Cancel Current Path
if Path.StatusType.Active == true then
Path:Stop()
end
Path:Run(nearestPlayer.PrimaryPart.Position)
else
isFollowing = false
end
end
end
local function Wander()
--Cancel Current Path
if Path.StatusType.Active == true then
Path:Stop()
end
self.Walk:Stop()
self.Idle:Play()
wait(math.random(2, 5))
self.Idle:Stop()
self.Walk:Play()
Path:Run(rig.PrimaryPart.Position + Vector3.new(math.random(-radius, radius), 0 , math.random(-radius, radius)))
end
-- Check for nearby players periodically
task.spawn(function()
while true do
if not isFollowing then
followPlayer()
end
wait() \
end
end)
-- Wandering
Path.Reached:Connect(function()
if not isFollowing then
Wander()
else
if not self.Walk.IsPlaying then
self.Idle:Stop()
self.Walk:Play()
end
Path:Run(nearestPlayer.PrimaryPart.Position)
end
end)
Path.WaypointReached:Connect(function()
if isFollowing then
if not self.Walk.IsPlaying then
self.Idle:Stop()
self.Walk:Play()
end
Path:Run(nearestPlayer.PrimaryPart.Position)
end
end)
Path.Error:Connect(function(errorType)
-- warn(errorType)
if isFollowing then
if not self.Walk.IsPlaying then
self.Idle:Stop()
self.Walk:Play()
end
Path:Run(nearestPlayer.PrimaryPart.Position)
else
Wander()
end
end)
--Dummy knows to compute path again if something blocks the path
Path.Blocked:Connect(function()
if isFollowing then
if not self.Walk.IsPlaying then
self.Idle:Stop()
self.Walk:Play()
end
Path:Run(nearestPlayer.PrimaryPart.Position)
else
if Path.StatusType.Active == true then
Path:Stop()
end
Path:Run(rig.PrimaryPart.Position + Vector3.new(math.random(-radius, radius), 0, math.random(-radius, radius)))
end
end)
-- Start wandering initially
Path:Run(rig.PrimaryPart.Position + Vector3.new(math.random(-radius, radius), 0, math.random(-radius, radius)))
end
Here is my currently enemy code, not sure how I’m able to fully optimize it but help would be apprecitaed
please help, wth do i do when this happens?
ServerStorage.SimplePath:327: attempt to perform arithmetic (sub) on number and nil
Same here. I set the NPC’s WalkSpeed to 18 and it causes the NPC to stutter which makes it slower. Have you found a solution yet?
I dont know why, but after Path:Destroy()
(i think), its still gives an error like:
attempt to index nil with 'Status'
Also experiencing this issue. It seems to occur once you’ve destroyed a path once and now want to create a new one.
When I have multiple npcs, and I use Path:Destroy(), it says attempt to call missing method Destroy() on table
Really good module! Easy to use, and working perfectly!