I want to make the pathfinding NPC randomly go to one of the waypoints in the way points folder but I also want the npc to not go to a previous waypoint. the function for going to a waypoint is in line 483. I can’t figure out how to make the NPC not walk to a previous waypoint.
I’ve tried looking into paths and pathfinding on the doc but nothing there, ive tried many methods but the only one that works is destroying the waypoints but theres going to be more npcs that use the same waypoints and im not going to be duplicating waypoints 10 times thats just gonna make the game laggy.
So please can anyone help me figure out how to make the NPC not go to a previous waypoint?
local function Error(code)
--warn("Error: "..code)
end
local function Work(code)
-- print("Working: "..code)
end
local function Point(code)
--print("Target: "..code)
end
local newinsatce
if script.Started.Value == false then
script.Started.Value = true
script.Parent.Others.ConfigurationValues.Stuck.TP.Effect.TpEffect.Parent = script.Parent.Parent.PrimaryPart
Instance.new("BoolValue", script.Parent).Name = "Chasing"
newinsatce = Instance.new("Motor6D")
newinsatce.Parent = script.Parent.Parent.HumanoidRootPart
newinsatce.Part0 = script.Parent.Parent.HumanoidRootPart
newinsatce.Part1 = script.FakeHumanoidRootPart
script.FakeHumanoidRootPart.Parent = script.Parent.Parent
Instance.new("BoolValue", script.Parent).Name = "Pause"
wait()
end
local Pause = script.Parent:WaitForChild("Pause")
local MainFolder = script.Parent.Parent.Parent
local folder = script.Parent.Parent.Parent
local ConfigureFolder = script.Parent.Others.ConfigurationValues
local AI = script.Parent.Parent
local Pathfinding = game:GetService("PathfindingService")
local Hum = AI:WaitForChild("Humanoid")
local RootPart = AI:WaitForChild("HumanoidRootPart")
local hipH = Hum.HipHeight
local PathInfo = {
["AgentHeight"] = ((hipH > 0 and hipH)or 4),
["AgentRadius"] = ((RootPart.Size.X > 0 and RootPart.Size.X) or RootPart.Size.Y),
["AgentCanJump"] = ((true ~= true) or false)
}
--local normSpeed = Hum.WalkSpeed
local value = AI.Configuration:FindFirstChild("Chasing")
local events = game:GetService("ReplicatedStorage"):WaitForChild("Events_Ai")
local CameraShakes = ConfigureFolder.Shake["CanShake?"].Value
local ShakeMagNear = ConfigureFolder.Shake.MagNear.Value
local ShakeMagFar = ConfigureFolder.Shake.MagFar.Value
local ShakeMagFarthest = ConfigureFolder.Shake.MagFarthest.Value
local chaseOn = events:WaitForChild("On")
local chaseOff = events:WaitForChild("Off")
local running = events:WaitForChild("running")
chaseOff:FireAllClients()
running.Value = false
Pause.Value = false
value.Value = true
--Hum.WalkSpeed = ConfigureFolder.Chase["Normal Speed"].Value
local CanJumpscare = ConfigureFolder.Jumpscare["CanJumpscare?"].Value
local Sounds = ConfigureFolder.Parent["Configuration - Sounds"]:WaitForChild("Sounds")
local Animations = ConfigureFolder.Parent["Configuration - Animations"]:WaitForChild("Animations")
local ts = game:GetService("TweenService")
local oldCframe = RootPart.CFrame
local movingPart = nil
local Torso = nil
if script.StartParts.Value == false then
script.StartParts.Value = true
if(script.Jumpscare1)then script.Jumpscare1.Parent=(AI)script.Jumpscare2.Parent=(AI)--[[ConfigureFolder.Parent["Configuration - Motor"].Jumpscare.Jumpscare1.Parent=(RootPart)ConfigureFolder.Parent["Configuration - Motor"].Jumpscare.Jumpscare2.Parent=(RootPart)]]end
end
local IsRandomPath = ConfigureFolder.Path.RandomPaths.Value
local PathPartName = ConfigureFolder.Path.NameParts.Value
local StopDelay = ConfigureFolder.Path.StopDelay.Value
local PathwaysParts = ConfigureFolder.Path.PathsFolder.Value
local mxPaths= #PathwaysParts:GetChildren()
local curPath=1
local candamage = ConfigureFolder.Damage["CanDamage?"].Value
local mxDmg = ConfigureFolder.Damage.Damage.Value
local DmgWhenFullyTouch = ConfigureFolder.Damage["Damage When Really Touch"].Value
local DmgDistance = ConfigureFolder.Damage["Damage Distance"].Value
local dmgDelay = ConfigureFolder.Damage["Damage Delay"].Value
local seeplayerlol = ConfigureFolder.Animation["See Player= Animation"].Value
local CanChangeAnim = ConfigureFolder.Animation["CanChangeAnimation?"].Value
local RunTrackSpeed = ConfigureFolder.Animation["Chase Animation Speed"].Value
local WalkTrackSpeed = ConfigureFolder.Animation["Walking Animation Speed"].Value
local VisionInfrontOnly = ConfigureFolder.Vision["Vision Front"].Value
local mxVisionDistance = ConfigureFolder.Vision["Vision Distance"].Value
local ChaseSpeed = ConfigureFolder.Chase["Chase Speed"].Value
local ChaseMusic= ConfigureFolder.Chase["Chase Music"].Value
local mxFov= ConfigureFolder.Chase["Chase Fov"].Value
local CanLockTargets = ConfigureFolder.Chase["Follow even when Target turns corner"].Value
local ChasePlaysWhenTargetLooking = ConfigureFolder.Chase["Chase Fov just if player see monster"].Value
local Scareanimation = Animations:WaitForChild('Jumpscare')
local Scarehumanoid = script.Parent.Parent:WaitForChild('Humanoid')
local Scaredance = Scarehumanoid:LoadAnimation(Scareanimation)
local Seeanimation = Animations:WaitForChild('SeePlayer')
local Seehumanoid = script.Parent.Parent:WaitForChild('Humanoid')
local Seedance = Seehumanoid:LoadAnimation(Seeanimation)
local iswalking = false
--Credits("1XxbiaxX Sky_OwP")
for i, getBodies in pairs(AI:GetDescendants()) do
if getBodies:IsA("Part") or getBodies:IsA("MeshPart") then
getBodies.Anchored = false
-- getBodies.CanCollide = false
end
end
local stuck = false
local RunTrack
local WalkTrack
local walkingToDoor = false
if Animations:WaitForChild("Walk").AnimationId ~= "" then
WalkTrack = Hum:LoadAnimation(Animations:WaitForChild("Walk"))
WalkTrack:AdjustSpeed(WalkTrackSpeed)
else
Error("Walk Id not Valid")
end
if Animations:WaitForChild("Run").AnimationId ~= "" then
RunTrack = Hum:LoadAnimation(Animations:WaitForChild("Run"))
RunTrack:AdjustSpeed(RunTrackSpeed)
else
Error("Run Id not Valid")
end
local function Jumpscare(Player)
if Player and CanJumpscare then
Work("Jumpscare")
Pause.Value = true
game.Players.RespawnTime = ConfigureFolder.Jumpscare["Jumpscare Heigh"].Value
Sounds.Jumpscare:Clone().Parent = events.Jumpscare
running.Value = false
chaseOff:FireClient(Player)
events.Jumpscare:FireClient(Player, AI, ConfigureFolder.Jumpscare["Jumpscare Time"].Value,ConfigureFolder.Jumpscare["flash screen dark"].Value,ConfigureFolder.Jumpscare["Smooth End Dark Screen"].Value,ConfigureFolder.Jumpscare["End Dark Screen"].Value,script.Parent.Others.ConfigurationValues.Jumpscare.ZoomJumpscare)
if ConfigureFolder.Fix["anti tripping by script"].Value == false then
RootPart.Anchored = true
end
script.Disabled = true
Hum.WalkSpeed = 0
WalkTrack:Stop()
RunTrack:Stop()
Scaredance:Play()
wait(Scaredance.Length)
wait(0.8)
Scaredance:Stop()
--Hum.WalkSpeed = normSpeed
WalkTrack:Play()
script.Disabled = false
RootPart.CanCollide = true
RootPart.Anchored = false
Pause.Value = false
end
end
Hum.Touched:Connect(function(hit)
if candamage == true then
if game.Players:GetPlayerFromCharacter(hit.Parent) and hit.Parent:FindFirstChild("Humanoid").Health > 0 and stuck == false then
hit.Parent:FindFirstChild("Humanoid").Health -= DmgWhenFullyTouch
hit.Parent:WaitForChild("Humanoid").Died:Connect(function()
Jumpscare(game:GetService("Players"):GetPlayerFromCharacter(hit.Parent))
end)
wait(dmgDelay)
end
end
end)
local animated = false
local function AnimRun()
if animated == true then
animated = false
if RunTrack ~= nil and CanChangeAnim then
RunTrack:Play()
if WalkTrack~=nil then
WalkTrack:Stop()
end
end
end
end
local function AnimWalk()
if animated == false then
animated = true
if WalkTrack ~= nil then
WalkTrack:Play()
if RunTrack~=nil then
RunTrack:Stop()
end
end
end
end
AI.PrimaryPart=RootPart
AI.PrimaryPart:SetNetworkOwner(nil)
local function RootHeight()
return (RootPart.Position - Vector3.new(0,hipH,0))
end
local function GetAIValues()
local v = MainFolder:GetDescendants()
for i, Gotten in pairs(v) do
if Gotten:IsA("BoolValue") and Gotten.Name == "Chasing" then
if Gotten.Value == true then
return true
end
end
end
end
local function TargetinVision(Target)
Work("New Point")
Point("Player")
if Target and Target:FindFirstChild("HumanoidRootPart") then
local origin = RootPart.Position
local direction = (Target.HumanoidRootPart.Position - RootPart.Position).unit * mxVisionDistance
local ray = Ray.new(origin,direction)
local ignoreList = {AI}
local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
if ConfigureFolder.Vision["CanSee?"].Value == true then
if hit and Target:FindFirstChild("HumanoidRootPart") then
if hit:IsDescendantOf(Target) then
if VisionInfrontOnly then
local unit = (Target.HumanoidRootPart.Position - RootHeight()).Unit
local isLooking = RootPart.CFrame.LookVector
local Dot = unit:Dot(isLooking)
if Dot > 0 then
return true
end
else
return true
end
end
else
return false
end
end
end
end
local function AI_Turn(Target)
if Target and Target:FindFirstChild("HumanoidRootPart") then
local origin = RootPart.Position
local direction = (Target.HumanoidRootPart.Position - RootPart.Position).unit * 10000
local ray = Ray.new(origin,direction)
local hit, pos = workspace:FindPartOnRay(ray, AI)
if hit then
if hit:IsDescendantOf(Target) then
return true
end
else
return false
end
end
end
local function FindDoor()
for i, found in pairs(workspace:GetDescendants()) do
if found:IsA("Part") or found:IsA("MeshPart") then
local mxdist = (RootPart.Position - found.Position).Magnitude
local origin = RootPart.Position
local direct = (found.Position - origin).unit * mxdist
local ray = Ray.new(origin,direct)
local hit, pos = workspace:FindPartOnRay(ray, AI)
local nearestDoor = nil
if hit then
if hit.Parent:FindFirstChild("mainDoor") and hit.Parent.mainDoor:IsA("Script") then
nearestDoor = hit
return nearestDoor
end
break
else
return nil
end
end
end
end
local function Shaker(Target)
if CameraShakes and Target:FindFirstChild("HumanoidRootPart") then
if Sounds:FindFirstChild("Footsteps") then
Sounds:FindFirstChild("Footsteps").MaxDistance = ShakeMagFarthest
Sounds:FindFirstChild("Footsteps").MinDistance = ShakeMagNear
Sounds:FindFirstChild("Footsteps").Parent = RootPart
end
local Player = game:GetService("Players"):GetPlayerFromCharacter(Target)
local vsRoot = Target:WaitForChild("HumanoidRootPart")
local TotalDist = (RootPart.Position - vsRoot.Position).Magnitude
if TotalDist <= ShakeMagFarthest and TotalDist >= ShakeMagFar then
events:WaitForChild("Shaking"):FireClient(Player, 3, .4,script.Parent.Others.ConfigurationValues.Shake["Shake like Phantom Ai"].Value)
elseif TotalDist <= ShakeMagFar and TotalDist >= ShakeMagNear then
events:WaitForChild("Shaking"):FireClient(Player, 5,.4,script.Parent.Others.ConfigurationValues.Shake["Shake like Phantom Ai"].Value)
elseif TotalDist <= ShakeMagNear and TotalDist >= 0 then
events:WaitForChild("Shaking"):FireClient(Player, 10, .4,script.Parent.Others.ConfigurationValues.Shake["Shake like Phantom Ai"].Value)
end
end
end
local function PlayChaseSequence(Plyr, char)
if Plyr and char then
local TargetIsLooking = require(char:FindFirstChild("CharacterLooking"))
if ChasePlaysWhenTargetLooking then
if TargetIsLooking.IsLookingAtAI(AI) then
events:WaitForChild("On"):FireClient(Plyr, AI,mxFov)
end
else
events:WaitForChild("On"):FireClient(Plyr, AI, mxFov)
end
if ConfigureFolder.Vision["Tokito ai"].Value == true then
if TargetIsLooking.IsLookingAtAI(AI) then
Pause.Value = true
RootPart.Anchored = true
WalkTrack:AdjustSpeed(0)
RunTrack:AdjustSpeed(0)
else
wait(0.05)
if TargetIsLooking.IsLookingAtAI(AI) then
Pause.Value = true
RootPart.Anchored = true
WalkTrack:AdjustSpeed(0)
RunTrack:AdjustSpeed(0)
wait(0.05)
else
Pause.Value = false
RootPart.Anchored = false
WalkTrack:AdjustSpeed(WalkTrackSpeed)
RunTrack:AdjustSpeed(RunTrackSpeed)
wait(0.05)
end
end
end
end
end
local function IsStuck(stuck)
if Pause.Value == false then
if stuck == true then
Error("Stuck")
RootPart.CanCollide = false
else
RootPart.CanCollide = true
end
end
end
local function StopChaseSequence(Plyr, char)
Work("New Point")
if Plyr and char then
if not GetAIValues() then
running.Value = false
chaseOff:FireClient(Plyr)
if ConfigureFolder.Vision["Tokito ai"].Value == true then
Pause.Value = false
RootPart.Anchored = false
WalkTrack:AdjustSpeed(WalkTrackSpeed)
RunTrack:AdjustSpeed(RunTrackSpeed)
wait(1)
if ConfigureFolder.Vision["Tokito ai"].Value == true then
Pause.Value = false
RootPart.Anchored = false
WalkTrack:AdjustSpeed(WalkTrackSpeed)
RunTrack:AdjustSpeed(RunTrackSpeed)
end
end
end
end
end
local function StartAnimationLol()
if seeplayerlol == true then
Pause.Value = true
seeplayerlol = false
if ConfigureFolder.Fix["anti tripping by script"].Value == false then
script.Parent.Parent.HumanoidRootPart.Anchored = true
end
WalkTrack:Stop()
Sounds.SeePlayer:Play()
Seedance:Play()
wait(Seedance.Length)
Seedance:Stop()
RootPart.CanCollide = true
script.Parent.Parent.HumanoidRootPart.Anchored = false
Pause.Value = false
end
end
local function LockedTarget(Target,ReallySee)
if ReallySee == true then
StartAnimationLol()
end
Work("New Point")
Point("Player")
if ReallySee == true then
Hum.WalkSpeed = ChaseSpeed
end
local Player = game:GetService("Players"):GetPlayerFromCharacter(Target)
local vsRoot = Target:FindFirstChild("HumanoidRootPart")
local vsHum = Target:FindFirstChild("Humanoid")
local vsPath = Pathfinding:CreatePath(PathInfo)
vsPath:ComputeAsync(RootPart.Position, vsRoot.Position)
local TargetIsLooking = require(Target:FindFirstChild("CharacterLooking"))
if vsPath.Status == Enum.PathStatus.Success then
RootPart.CanCollide = true
for i, way in ipairs(vsPath:GetWaypoints()) do
if ReallySee == true then
AnimRun()
end
Hum:MoveTo(way.Position)
if AI_Turn(Target) and vsHum.Health > 0 and Player:FindFirstChild("Safe") and Player.Safe:IsA("BoolValue") and Player.Safe.Value == false and not Player:FindFirstChild("IsHiding") then
if ReallySee == true then
PlayChaseSequence(Player,Target)
value.Value = true
end
Hum:MoveTo(vsRoot.Position)
if ReallySee == true then
running.Value = true
end
vsPath:ComputeAsync(RootPart.Position, vsRoot.Position)
else
if vsHum.Health > 0 and Player:FindFirstChild("Safe") and Player.Safe:IsA("BoolValue") and Player.Safe.Value == false and not Player:FindFirstChild("IsHiding") then
local Moving = Hum.MoveToFinished:Wait()
if not Moving then
IsStuck(true)
else
IsStuck(false)
end
end
end
end
else
IsStuck(true)
end
end
local function TargetPlayer()
local Players = game.Players:GetPlayers()
local NearTarget
for i,Player in pairs(Players) do
if Player.Character then
local Target = Player.Character
local HumanoidRootPart = Target:FindFirstChild("HumanoidRootPart")
Shaker(Target)
if TargetinVision(Target) and Target.Humanoid.Health > 0 and HumanoidRootPart and Player:FindFirstChild("Safe") and Player.Safe:IsA("BoolValue") and Player.Safe.Value ==false and not Player:FindFirstChild("IsHiding") then
Hum:MoveTo(HumanoidRootPart.Position)
PlayChaseSequence(Player,Target)
NearTarget = Target
Hum.WalkSpeed = ChaseSpeed
if CanLockTargets then
LockedTarget(NearTarget,true)
end
else
StopChaseSequence(Player, Target)
end
end
end
return NearTarget
end
local function Attack(Target)
if Target and Target:FindFirstChild("HumanoidRootPart") and Target.Humanoid.Health > 0 then
local Distance = (RootPart.Position - Target.HumanoidRootPart.Position).Magnitude
if Distance > DmgDistance then
if CanLockTargets then
LockedTarget(Target, true)
else
Hum:MoveTo(Target.HumanoidRootPart.Position)
end
else
if candamage == true then
Target:WaitForChild("Humanoid").Health -=mxDmg
Target:WaitForChild("Humanoid").Died:Connect(function()
Hum.WalkSpeed = 0
Jumpscare(game.Players:GetPlayerFromCharacter(Target))
end)
wait(dmgDelay)
end
end
end
end
--local num = script.Parent.Parent.Num.Value
local function Pathfind(destination) -- TODO: PLAY ONCE THEN ITS THE LOOP, MAKE 7192 AUTO, MANUALLY TEST IT TO SEE IF IT WORKED THEN WOULD IT REALLY WORK?
--local already = script.Parent.Parent["7192"]
--local nextWaypointIndex
--[[
local success, errorMessage = pcall(function()
path:ComputeAsync(RootPart.Position, destination.Position)
end)
if success and path.Status == Enum.PathStatus.Success then
--]]
-- Get the path waypoints
-- Loop through the waypoints
--for i, destination in ipairs(waypoints) do
-- Check if the waypoint has already been visited
--print(VisitedWaypoints[num])
pcall(function()
local savedwaypoints = VisitedWaypoints
end)
local VisitedWaypoints = {}
if VisitedWaypoints ~= savedwaypoints then
VisitedWaypoints = savedwaypoints
end
local path = Pathfinding:CreatePath(PathInfo)
if VisitedWaypoints ~= destination then -- wavepoint num and the numbers below it
-- Move to the waypoint
--[[
VisitedWaypoints[#VisitedWaypoints+num] = destination -- Mark the waypoint as visited
--nextWaypointIndex = i
script.Parent.Parent.Num.Value = num + 1
--]]
print(destination)
--script.Parent.Parent.Num.Value = num + 1
local isVisited = false
for _, visited in ipairs(VisitedWaypoints) do
if visited == destination then
isVisited = true
break
end
end
if isVisited == false then
print(isVisited)
print(VisitedWaypoints)
table.insert(VisitedWaypoints, destination) -- Add destination to the table
print(VisitedWaypoints)
print("second print is up")
path:ComputeAsync(RootPart.Position, destination.Position)
end
--break
end
--end
--end
--[[
local already = Instance.new("StringValue"):Clone()
local once = true
pcall(function()
local stringValue = destination["7192"]
end)
if once == true then
local stringValue = nil
once = false
end
already.Parent = script.Parent.Parent
--print(2)
-- if not stringValue is the problem
if stringValue == nil then
-- or stringValue.Value ~= already.Value
if stringValue ~= nil then
print(stringValue.Value)
print(already.Value)
end
path:ComputeAsync(RootPart.Position, destination.Position)
already.Value = script.Parent.Parent.Name
already.Name = script.Parent.Parent.Name
already.Parent = destination
stringValue = destination["7192"]
end
print(stringValue)
print(already)
--print(stringValue.Value)
--]]
return path
end
local function Wandering(Location)
local path = Pathfind(Location)
if path.Status == Enum.PathStatus.Success then
for i,Waypoint in pairs(path:GetWaypoints()) do
if iswalking == false then
local Target = TargetPlayer()
local Player = game:GetService("Players"):GetPlayerFromCharacter(Target)
if Target and Target.Humanoid.Health > 0 and Player:FindFirstChild("Safe") and Player.Safe:IsA("BoolValue") and Player.Safe.Value == false then
Attack(Target)
break
elseif walkingToDoor==false then
RootPart.CanCollide = true
movingPart = Location
--Hum.WalkSpeed = normSpeed
AnimWalk()
value.Value = false
if iswalking == false then
Hum:MoveTo(Waypoint.Position)
end
local moveTime = Hum.MoveToFinished:Wait()
if not moveTime then
IsStuck(true)
else
IsStuck(false)
end
end
end
end
else
local DoorDetect = FindDoor()
if DoorDetect~=nil then
walkingToDoor = true
Hum:MoveTo(DoorDetect.Position + RootPart.CFrame.LookVector * 2)
Hum.MoveToFinished:Wait()
walkingToDoor = false
Wandering(Location)
else
walkingToDoor = true
Hum:MoveTo(Location.Position)
RootPart.CanCollide = false
Hum.MoveToFinished:Wait()
walkingToDoor = false
end
end
end
local function RandomPartWalk()
local waypointsParts = PathwaysParts:GetChildren()
local RandomNum = math.random(1, #waypointsParts)
Wandering(waypointsParts[RandomNum])
end
local function PartWalk()
if iswalking == false then
if curPath == mxPaths then
curPath = 1
else
curPath +=1
end
Wandering(PathwaysParts:FindFirstChild(PathPartName.. curPath))
end
end
game.Players.PlayerAdded:Connect(function(Plr)
if ConfigureFolder.Hear["CanHear?"].Value == true then
events.Hear:FireClient(Plr,script.Parent.Parent,script.Parent.Others.ConfigurationValues.Hear["HearLuck %"])
end
Plr.CharacterAdded:Connect(function()
if ConfigureFolder.Hear["CanHear?"].Value == true then
events.Hear:FireClient(Plr,script.Parent.Parent,script.Parent.Others.ConfigurationValues.Hear["HearLuck %"])
end
end)
end)
local function HeartTarget(player,Target)
local randomHearIfTrue = math.random(0,100)
if randomHearIfTrue <= script.Parent.Others.ConfigurationValues.Hear["HearLuck %"].Value then
wait(math.random(0.5,2))
iswalking = true
LockedTarget(Target,false)
wait(0.1)
iswalking = false
end
--iswalking = false
if IsRandomPath then
return RandomPartWalk()
else
return PartWalk()
end
end
events.Hear.OnServerEvent:Connect(HeartTarget)
repeat wait()until game:WaitForChild("Workspace",1)
while game:GetService("RunService").Heartbeat:Wait() do
wait(StopDelay)
if iswalking == false then
if stuck == false or Pause.Value == false then
if IsRandomPath then
RandomPartWalk()
else
PartWalk()
end
end
end
if ConfigureFolder.Hear["CanHear?"].Value == true then
events.Hear:FireAllClients(script.Parent.Parent,script.Parent.Others.ConfigurationValues.Hear["HearLuck %"])
end
end