And when it prints that he needs to jump, he doesn’t jump. (he makes me lag alot too)
I have a fairly advanced Zombie AI with pathfinding that I believe you may find useful since your NPC seems to be similar to a zombie. But the script will probably need some modifications of course.
local pathservice = game:GetService("PathfindingService")
local runservice = game:GetService("RunService")
local players = game:GetService("Players")
local path = pathservice:CreatePath()
local rand = Random.new(tick()%1*2e6)
local function WaitEvent(ev,t)
local obj = Instance.new("BoolValue")
local returns
local c;c = ev:Connect(function(...)
c:Disconnect()
c = nil
returns = {...}
obj.Value = true
end)
do
coroutine.wrap(function()
local ti = tick()
local waitTime = t
while (tick()-ti < waitTime) do
if (returns) then return end
waitTime = t + runservice.Heartbeat:Wait()
end
if (returns) then return end
c:Disconnect()
obj.Value = true
end)()
end
obj:GetPropertyChangedSignal("Value"):Wait()
obj:Destroy()
return (returns) and unpack(returns) or nil
end
local dir = Vector3.new(0,-4,0)
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist
--params.FilterDescendantsInstances = {workspace.Zombies}
local function CheckSight(root,target)
local dif = target.Position-root.Position
local mag = dif.Magnitude
local ray = Ray.new(root.Position,dif.Unit*mag)
local p = workspace:FindPartOnRay(ray,root.Parent.Parent)
if ((p) and (p:IsDescendantOf(target.Parent)) and (math.abs(target.Position.Y-root.Position.Y) < 3)) then
if (mag <= 20) then
local mid = root.Position:Lerp(target.Position,0.5)
local p = workspace:Raycast(mid,dir,params)
if (not p) then
return false
end
else
for i = 0.125,0.875,0.125 do
local mid = root.Position:Lerp(target.Position,i)
local p = workspace:Raycast(mid,dir,params)
if (not p) then
return false
end
end
end
--print("ey")
return true
end
return false
end
for _,v in pairs(script.Parent:GetDescendants()) do
if (v:IsA("BasePart")) then
v:SetNetworkOwner()
end
end
local jumpstates = {
Enum.HumanoidStateType.Running;
Enum.HumanoidStateType.RunningNoPhysics;
}
local function Jump(humanoid)
local state = humanoid:GetState()
if (not table.find(jumpstates,state)) then
local c;c = humanoid.StateChanged:Connect(function(state)
if (not table.find(jumpstates,state)) then return end
c:Disconnect()
c = nil
humanoid.Jump = true
end)
else
humanoid.Jump = true
end
return true
end
local function FindNearestPlayer()
local plrs = players:GetPlayers()
local nearPlr,near
for i = 1,#plrs do
local v = plrs[i]
if ((v.Name ~= script.Parent.Name) and (v.Character) and (v.Character.Humanoid.Health > 0)) then
local mag = (script.Parent.HumanoidRootPart.Position-v.Character.HumanoidRootPart.Position).Magnitude
if (not near) then
near = mag
nearPlr = v.Character.HumanoidRootPart
elseif (near > mag) then
near = mag
nearPlr = v.Character.HumanoidRootPart
end
end
end
return nearPlr
end
-- // Zombie Damage \\ --
--[[local coolDown = {}
script.Parent.HumanoidRootPart.Touched:Connect(function(hit)
if (hit.Parent.Name == script.Parent.Name) then return end
local hum = hit.Parent:FindFirstChild("Humanoid")
if ((not hum) or (coolDown[hum])) then return end
coolDown[hum] = true
hum:TakeDamage(10)
wait(1)
coolDown[hum] = nil
end)]]
---------------------------
while true do
local root = FindNearestPlayer()
if (root) then
local isVisible = CheckSight(script.Parent.HumanoidRootPart,root)
if (isVisible) then
script.Parent.Humanoid:MoveTo(root.Position)
wait()
else
path:ComputeAsync(script.Parent.HumanoidRootPart.Position,root.Position)
if (path.Status == Enum.PathStatus.Success) then
local wp = path:GetWaypoints()
for i = 3,#wp do
local v = wp[i]
if (v.Action == Enum.PathWaypointAction.Jump) then
Jump(script.Parent.Humanoid)
end
script.Parent.Humanoid:MoveTo(v.Position)
local reached = WaitEvent(script.Parent.Humanoid.MoveToFinished,1)
if (not reached) then
--print("stuck!")
Jump(script.Parent.Humanoid)
break
end
if (CheckSight(script.Parent.HumanoidRootPart,root)) then
script.Parent.Humanoid:MoveTo(root.Position)
break
end
if ((root.Position-wp[#wp].Position).Magnitude >= 40) then
if ((root.Position-script.Parent.HumanoidRootPart.Position).Magnitude <= 20) then
script.Parent.Humanoid:MoveTo(root.Position)
elseif (wp[i+1]) then
script.Parent.Humanoid:MoveTo(wp[i+1].Position)
end
--print("target moved")
break
end
end
wait()
else
--print("couldnt find path")
script.Parent.Humanoid:MoveTo(root.Position)
wait(0.1)
end
end
else
wait()
end
end
Just put this script inside the NPC and it should work, you may need to make some modifications to it. I could probably explain how it works but I don’t have the time right now.
The script is open-source so anyone can use it if they want.
Wow that is too confusing for me. I can’t use this or I will just be so confused.
Well I might as well use it or i wouldn’t have a good game.
How do I change the scanning distance?
I know it is frustrating when you don’t know the logic behind the code. But sometimes you have to use it until you get better and finally start to understand how it works. It happens with me as well.
It jutters alot when it moves, how can I fix it.
I don’t know what you are talking about it works perfect for me.
Oh for me it sometimes stops for a sec then starts again.
Which makes it delay and lag - so to speek.
I would send a video but :/
I dunno…
Yeah a video will be helpful to find out the problem.
I might just use my regular one which uses :MoveTo with no jump if there is no fix for it :/
Oh ok, I will send a vid, hold on.
It isn’t doing it now… how weird!!
Also I got a message in output saying “Failing to check if player is in group”
Oh it isn’t doing it now bc I changed to the regular follow, whoops
That isn’t related to the script, its a problem with Roblox’s core scripts or Roblox’s servers, or another script.
Ok, let me send a video once again :/
He, like, lags when he turns…