In order to fix my chasing NPC’s walking animation, which kept stuttering (probably a delay whenever a waypoint was reached), I decided to use the Path:Run() function only if it’s necessary because of obstacles in the way and go with Humanoid:MoveTo() instead.
This solution fixes the stutter but the Raycast doesn’t work properly because now, my NPC almost never uses the Path:Run() function and gets stuck trying to chase me without avoiding obstacles. If there is an obstacle the Raycast SOMETIMES detects it but mostly, my script just runs Humanoid:MoveTo()
local RepStorage = game:GetService("ReplicatedStorage")
local SimplePath = require(RepStorage:WaitForChild("Modules"):WaitForChild("SimplePath"))
function run(Goal, enemy, Path)
if Goal ~= nil and enemy:FindFirstChild("Humanoid") ~= nil then
if enemy.Humanoid.Health > 0 then
Path:Run(Goal)
end
end
end
game.Workspace:WaitForChild("Map_Sriptable"):WaitForChild("Agents").ChildAdded:Connect(function(enemy)
if enemy:WaitForChild("Target").Value.Name == game.Players.LocalPlayer.Name then
local Target = enemy:WaitForChild("Target")
local Goal = Target.Value:WaitForChild("HumanoidRootPart")
--Create a new Path using the Dummy
local Path = SimplePath.new(enemy)
--breaking the loops
local breaking = false
--Set goal to respawned character
game.Players.LocalPlayer.CharacterAdded:Connect(function(char)
if enemy then
Goal = Target.Value:WaitForChild("HumanoidRootPart")
end
end)
--Make visible
for _, v in pairs(enemy:GetDescendants()) do
if v:IsA("BasePart") or v:IsA("Decal") then
if v.Name ~= "HumanoidRootPart" and v.Name ~= "Hitbox" then
v.Transparency = 0
end
elseif v:IsA("BillboardGui") then
v.Enabled = true
elseif v:IsA("Sound") then
v.Volume = 0.5
end
end
enemy.Humanoid.Died:Connect(function()
Path:Stop()
end)
Path.Visualize = true
--follow target
while true do
while Goal ~= nil and enemy:FindFirstChild("Humanoid") ~= nil do
if enemy.Humanoid.Health > 0 then
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = {enemy, Target.Value}
local raycastResult = workspace:Raycast(enemy.HumanoidRootPart.Position, (Target.Value:WaitForChild("HumanoidRootPart").Position - enemy.HumanoidRootPart.Position).Unit, raycastParams)
if raycastResult then
if raycastResult.Instance then
--print(raycastResult.Instance)
Path:Run(Goal)
--print("path")
else
enemy.Humanoid:MoveTo(Target.Value:WaitForChild("HumanoidRootPart").Position)
task.wait()
--print("walk")
end
else
enemy.Humanoid:MoveTo(Target.Value:WaitForChild("HumanoidRootPart").Position)
task.wait()
--print("walk 2")
end
end
end
if breaking == true then
breaking = false
Path:Stop()
break
end
end
else
enemy:Destroy()
end
end)
The Path:Run() function handles the pathfinding and yields to a certain point so task.wait isnt needed SimplePath - Pathfinding Module