Okay, so i have a sample NPC, just need pathfinding. ive used a template in the past but the type of pathfinding i want is like this for example, Baldi walks in the middle between walls during waypoints. i tried to make a edit of my template pathfinding to make it do that but it failed horribly, if anyone can help me out on this please do, thank you. (also heres the pathfinding script btw)
--DuruTeru --[[ ____________________________________________________________________________________________________________________ i smell leik beef =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ____________________________________________________________________________________________________________________ ___ ___ ( ) ( ) .-. .--. .--. | |_ | |_ ( __) ___ .-. .--. .--. / _ \ / \ ( __) ( __) (''") ( ) \ / \ / _ \ . .' `. ; | .-. ; | | | | | | | .-. . ; ,-. ' . .' `. ; | ' | | | | | | | | ___ | | ___ | | | | | | | | | | | ' | | _\_`.(___) | |/ | | |( ) | |( ) | | | | | | | | | | _\_`.(___) ( ). '. | ' _.' | | | | | | | | | | | | | | | | | | ( ). '. | | `\ | | .'.-. | ' | | | ' | | | | | | | | | ' | | | | `\ | ; '._,' ' ' `-' / ' `-' ; ' `-' ; | | | | | | ' `-' | ; '._,' ' '.___.' `.__.' `.__. `.__. (___) (___)(___) `.__. | '.___.' ( `-' ; `.__. ____________________________________________________________________________________________________________________ =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ____________________________________________________________________________________________________________________ --]] local SearchDistance = 10000 -- How far a player can be before it detects you local ZombieDamage = 25 -- How much damage the Zombie inficts towards the player local DamageWait = 2 -- How many seconds to wait before it can damage the player again local WanderX, WanderZ = 30, 30 -- How many studs the zombie can wander on the x and z axis in studs ; 0, 0 to stay still --[[ ____________________________________________________________________________________________________________________ =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ____________________________________________________________________________________________________________________ --]] function getHumanoid(model) for _, v in pairs(model:GetChildren())do if v:IsA'Humanoid' then return v end end end local zombie = script.Parent local human = getHumanoid(zombie) local hroot = zombie.HumanoidRootPart local zspeed = hroot.Velocity.magnitude local head = zombie:FindFirstChild'Head' local vars = script.vars local pfs = game:GetService("PathfindingService") local players = game:GetService('Players') -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- local path local waypoint local chaseName = nil function GetTorso(part) local chars = game.Workspace:GetChildren() local chaseRoot = nil local chaseTorso = nil local chasePlr = nil local chaseHuman = nil local mag = SearchDistance for i = 1, #chars do chasePlr = chars[i] if chasePlr:IsA'Model' and chasePlr ~= zombie then chaseHuman = getHumanoid(chasePlr) chaseRoot = chasePlr:FindFirstChild'HumanoidRootPart' if chaseRoot ~= nil and chaseHuman ~= nil and chaseHuman.Health > 0 and chaseHuman.Name ~= "Zombie" then if (chaseRoot.Position - part).magnitude < mag then chaseName = chasePlr.Name chaseTorso = chaseRoot mag = (chaseRoot.Position - part).magnitude end end end end return chaseTorso end function GetPlayersBodyParts(t) local torso = t if torso then local figure = torso.Parent for _, v in pairs(figure:GetChildren())do if v:IsA'Part' then return v.Name end end else return "HumanoidRootPart" end end -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- local damagetime local damagedb = false for _, zambieparts in pairs(zombie:GetChildren())do if zambieparts:IsA'Part' and human.Health > 0 then zambieparts.Touched:connect(function(p) if p.Parent.Name == chaseName and p.Parent.Name ~= zombie.Name and not damagedb then -- damage damagedb = true damagetime = time() local enemy = p.Parent local enemyhuman = getHumanoid(enemy) vars.Attacking.Value = true enemyhuman:TakeDamage(ZombieDamage) vars.Attacking.Value = false while wait() do if damagetime ~= nil and time() >= (damagetime + DamageWait) then damagedb = false damagetime = nil end end end end) end end -- wandering spawn(function() while vars.Wandering.Value == false and human.Health > 0 do vars.Chasing.Value = false vars.Wandering.Value = true local desgx, desgz = hroot.Position.x+math.random(-WanderX,WanderX), hroot.Position.z+math.random(-WanderZ,WanderZ) local function checkw(t) local ci = 3 if ci > #t then ci = 3 end if t[ci] == nil and ci < #t then repeat ci = ci + 1 wait() until t[ci] ~= nil return Vector3.new(1,0,0) + t[ci] else ci = 3 return t[ci] end end path = pfs:FindPathAsync(hroot.Position, Vector3.new(desgx, 0, desgz)) waypoint = path:GetWaypoints() local connection; local direct = Vector3.FromNormalId(Enum.NormalId.Front) local ncf = hroot.CFrame * CFrame.new(direct) direct = ncf.p.unit local rootr = Ray.new(hroot.Position, direct) local phit, ppos = game.Workspace:FindPartOnRay(rootr, hroot) if path and waypoint or checkw(waypoint) then if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then human:MoveTo( checkw(waypoint).Position ) human.Jump = false end if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Jump then connection = human.Changed:connect(function() human.Jump = true end) human:MoveTo( waypoint[4].Position ) else human.Jump = false end if connection then connection:Disconnect() end else for i = 3, #waypoint do human:MoveTo( waypoint[i].Position ) end end wait(math.random(4,6)) vars.Wandering.Value = false end end) -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- while wait() do local nrstt = GetTorso(hroot.Position) if nrstt ~= nil and human.Health > 0 then -- if player detected vars.Wandering.Value = false vars.Chasing.Value = true local function checkw(t) local ci = 3 if ci > #t then ci = 3 end if t[ci] == nil and ci < #t then repeat ci = ci + 1 wait() until t[ci] ~= nil return Vector3.new(1,0,0) + t[ci] else ci = 3 return t[ci] end end path = pfs:FindPathAsync(hroot.Position, nrstt.Position) waypoint = path:GetWaypoints() local connection; local direct = Vector3.FromNormalId(Enum.NormalId.Front) local ncf = hroot.CFrame * CFrame.new(direct) direct = ncf.p.unit local rootr = Ray.new(hroot.Position, direct) local phit, ppos = game.Workspace:FindPartOnRay(rootr, hroot) if path and waypoint or checkw(waypoint) then if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then human:MoveTo( checkw(waypoint).Position ) human.Jump = false end if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Jump then connection = human.Changed:connect(function() human.Jump = true end) human:MoveTo( waypoint[4].Position ) else human.Jump = false end hroot.Touched:connect(function(p) local bodypartnames = GetPlayersBodyParts(nrstt) if p:IsA'Part' and not p.Name == bodypartnames and phit and phit.Name ~= bodypartnames and phit:IsA'Part' and rootr:Distance(phit.Position) < 5 then connection = human.Changed:connect(function() human.Jump = true end) else human.Jump = false end end) if connection then connection:Disconnect() end else for i = 3, #waypoint do human:MoveTo( waypoint[i].Position ) end end path = nil waypoint = nil elseif nrstt == nil then -- if player not detected vars.Wandering.Value = false vars.Chasing.Value = false CchaseName = nil path = nil waypoint = nil human.MoveToFinished:Wait() end end -- Base script for NPC enemy movement, -- still a work in progress end