-
I am trying to develop an efficient, non-hesitating zombie.
-
The current script I am using (see source script below) for the zombie makes the zombie stop for a few seconds after a player has moved. Basically, I am trying to make my zombie act like zombies in Zombie Rush, which generate new paths instantly, as soon as a player moves and doesn’t have to wait a few seconds (unlike my zombie at the moment).
-
I have researched beforehand on this topic and no topics have answered my problem as of yet.
I also want my zombie to constantly be moving towards each waypoint without stopping (also like Zombie Rush)
Source Script:
local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")
local lowerTorso = script.Parent:WaitForChild("Torso")
local clone = script.Parent:Clone()
function walkRandomly()
local xRand = math.random(-50, 50)
local zRand = math.random(-50, 50)
local goal = myRoot.Position + Vector3.new(xRand,0,zRand)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position, goal)
local waypoints = path:GetWaypoints()
myHuman.WalkSpeed = 20
if path.Status == Enum.PathStatus.Success then
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = task.wait(myHuman.MoveToFinished)
if not timeOut then
print("Got stuck")
myHuman.Jump = true
walkRandomly()
break
end
end
else
print("Path failed from random")
wait(1)
walkRandomly()
end
end
function findPath(target)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position,target.Position)
local waypoints = path:GetWaypoints()
myHuman.WalkSpeed = 20
if path.Status == Enum.PathStatus.Success then
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = myHuman.MoveToFinished:Wait(0.000001)
if not timeOut then
myHuman.Jump = true
print("Path too long!")
findPath(target)
break
end
if checkSight(target) then
repeat
print("Moving directly to the target")
myHuman.WalkSpeed = 16
myHuman:MoveTo(target.Position)
attack(target)
wait(0.000001)
if target == nil then
break
elseif target.Parent == nil then
break
end
until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
break
end
if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
print("Target has moved, generating new path")
findPath(target)
break
end
end
else
myHuman.WalkSpeed = 16
walkRandomly()
--myHuman:MoveTo(target.Position)
end
end
function checkSight(target)
local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
if hit then
if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 10 then
print("I can see the target")
return true
end
end
return false
end
function findTarget()
local dist = 500
local target = nil
local potentialTargets = {}
local seeTargets = {}
for i, v in ipairs(workspace:GetChildren()) do
local Torso = v:FindFirstChild("Torso") or v:findFirstChild("HumanoidRootPart")
local Humanoid = v:findFirstChild("Humanoid")
local Zombie = v:FindFirstChild("RealZombieScript")
if (Torso ~= nil) and (Humanoid ~= nil) and (Humanoid.Health > 0) and (Zombie == nil) then
if (myRoot.Position - Torso.Position).magnitude < dist and Humanoid.Health > 0 then
table.insert(potentialTargets,Torso)
end
end
end
if #potentialTargets > 0 then
for i, v in ipairs(potentialTargets) do
if checkSight(v) then
table.insert(seeTargets, v)
elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
end
if #seeTargets > 0 then
dist = 400
for i,v in ipairs(seeTargets) do
if (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
end
--if target then
-- if math.random(20) == 1 then
-- end
--end -- could be used for random attacks
return target
end
function attack(target)
if (myRoot.Position - target.Position).magnitude < 5 then
if target.Parent ~= nil then
target.Parent.Humanoid:TakeDamage(25)
wait(0.5)
end
end
end
function died()
wait(1)
--clone.Parent = workspace
game:GetService("Debris"):AddItem(script.Parent, 0.1)
end
myHuman.Died:Connect(died)
lowerTorso.Touched:Connect(function(obj)
if not obj.Parent:FindFirstChild("Humanoid") then
myHuman.Jump = true
end
end)
function main()
local target = findTarget()
if target then
myHuman.WalkSpeed = 16
findPath(target)
else
myHuman.WalkSpeed = 16
walkRandomly()
end
end
while wait(0.1) do
if myHuman.Health < 1 then
break
end
main()
end