Video
I want to achieve:
That the zombie opens door, follows player
Here’s a testing game:
ZombiePathFindingServiceNotWorkingCorrectly.rbxl (128,5 KB)
It uses a bit of raycast, Magnitude calculation
Extra information:
When it opens door it keeps walking against door , thats what I am trying to fix.
Ai Script
local myHuman = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("HumanoidRootPart")
local head = script.Parent:WaitForChild("Head")
local lowerTorso = script.Parent:WaitForChild("LowerTorso")
local collectionservice = game:GetService("CollectionService")
local grab = script.Parent:WaitForChild("Grab")
local grabAnim = myHuman:LoadAnimation(grab)
grabAnim.Priority = Enum.AnimationPriority.Action
local grabSound = head:WaitForChild("Attack")
local screamSound = head:WaitForChild("Scream")
local clone = script.Parent:Clone()
function findPath(target)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position,target.Position)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
local doors = collectionservice:GetTagged("Door")
for i,v in pairs(doors) do
if (script.Parent.HumanoidRootPart.Position-v.Center.Position).Magnitude < v.MaxDistance.Value then
if v.Open.Value == false then
local a = require(v.OpenDoor)
a:opendoor(script.Parent)
wait(.3)
end
end
end
myHuman:MoveTo(waypoint.Position)
--local timeOut = myHuman.MoveToFinished:Wait(1)
--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:MoveTo(target.Position)
wait(0.1)
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
end
end
function checkSight(target)
local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 5)
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) < 3 then
print("I can see the target")
return true
end
end
return false
end
function findTarget()
local dist = 300
local target = nil
local potentialTargets = {}
local seeTargets = {}
for i,v in ipairs(workspace:GetChildren()) do
local human = v:FindFirstChild("Humanoid")
local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
if human and torso and v.Name ~= script.Parent.Name then
if (myRoot.Position - torso.Position).magnitude < dist and human.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 = 200
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
screamSound:Play()
end
end
return target
end
local debonce = false
for i,v in pairs(script.Parent:GetChildren()) do
if v:IsA("BasePart") then
v.Touched:connect(function(hit)
local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
if plr and not debonce then
debonce=true
hit.Parent.Humanoid:TakeDamage(25)
wait(.3)
debonce=false
end
end)
end
end
function died()
wait(5)
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 = 12
findPath(target)
end
end
while wait(0.1) do
if myHuman.Health < 1 then
break
end
main()
end
Door Module
local module = {}
local open = false
local debounce = false
local distance = script.Parent.MaxDistance.Value
local function rotatedoor(xd)
local start = script.Parent.PrimaryPart.CFrame
local finish = script.Parent.PrimaryPart.CFrame * CFrame.Angles(0,math.rad(xd),0)
for i=0,1,.1 do
local cfm = start:Lerp(finish,i)
script.Parent:SetPrimaryPartCFrame(cfm)
wait()
end
script.Parent:SetPrimaryPartCFrame(finish)
end
local function opendoor()
if open then
rotatedoor(-90)
else
rotatedoor(90)
end
end
function module:opendoor(char)
if char then
if (char.HumanoidRootPart.Position-script.Parent.Center.Position).Magnitude > distance then
return
end else return
end
if not debounce then
debounce=true
open=not open
opendoor()
debounce=false
end
script.Parent.Open.Value=open
end
return module
Door Script
local module = require(script.Parent.OpenDoor)
local collectionservice = game:GetService("CollectionService")
collectionservice:AddTag(script.Parent,"Door")
script.Parent.RemoteEvent.OnServerEvent:Connect(function(plr)
module:opendoor(plr.Character)
end)