Hello,
I’m making a game like piggy and am currently making the AI for it. It works fine, but it Jitters. What I mean by this is, is if a player moves when the NPC is still walking, it still goes to their old position before going to their new one.
Video of what I mean:
https://gyazo.com/850a15a7ea4fad0710f296246fc9c770
Here is my script:
local pathservice = game:GetService("PathfindingService")
local runservice = game:GetService("RunService")
local players = game:GetService("Players")
local pathParams = {
["AgentHeight"] = 20,
["AgentRadius"] = 20,
["AgentCanJump"] = true
}
local path = pathservice:CreatePath(pathParams)
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
Thanks for any help!