Howdy forums,
I’ve been trying to figure out how pathfinding works for a while now, and I can’t seem to nail down how to get a monster npc to wander the map, but when it sees a player to chase them. I’ve tried and the below script is the closest I can get. I’m not sure why but when the target player moves out of the way, the script doesn’t update with the new position of the target player, and Debra (The monster) just slams into the wall. The video and her script is attached below. All help is greatly appreciated, as I’ve exhausted every other resource I could find.
local PathfindingService = game:GetService("PathfindingService")
local Debra = script.Parent
local hum = Debra:WaitForChild("Humanoid")
local currentWaypointIndex = 1
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Ev = ReplicatedStorage.Events.KillCam
for i,v in pairs(script.Parent:GetDescendants()) do
if v:IsA("Part") or v:IsA("MeshPart") then
v:SetNetworkOwner(nil)
end
end
local pathParams = {
AgentHeight = 9,
AgentRadius = 5,
AgentCanJump = false,
WaypointSpacing = 2,
Costs = {
Bricks = 1,
Plastic = 1,
SmoothPlastic = 1,
Wood = 1,
}
}
hum:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
hum:SetStateEnabled(Enum.HumanoidStateType.FallingDown, false)
local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances = {Debra}
for i,v in pairs(game.Workspace:GetDescendants()) do
if v.Name == "FirstAidStation" or v.Name == "StorageContainers" then
rayParams.FilterDescendantsInstances = {v}
end
end
local lastPos
local status
local Range = 200
local function canSeeTarget(target)
if target ~= nil then
local origin = Debra.HumanoidRootPart.Position
local direction = (target.HumanoidRootPart.Position - Debra.HumanoidRootPart.Position).Unit * Range
local ray = workspace:Raycast(origin, direction, rayParams)
if ray and ray.Instance then
if ray.Instance:IsDescendantOf(target) and not target:FindFirstChild("Hiding") then
return true
else
return false
end
else
return false
end
end
end
local function findTarget()
local players = game.Players:GetChildren()
local maxDistance = Range
local nearestTarget
for i, player in pairs(players) do
if player.Character then
local target = player.Character
local distance = (Debra.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
if distance < maxDistance and canSeeTarget(target) then
nearestTarget = target
maxDistance = distance
end
end
end
return nearestTarget
end
local function getPath(destination)
local path = PathfindingService:CreatePath(pathParams)
path:ComputeAsync(Debra.HumanoidRootPart.Position, destination.Position)
if path.Status == Enum.PathStatus.NoPath then
local H = Instance.new("Highlight")
H.Parent = destination
end
if path.Status == Enum.PathStatus.Success then
for i,v in pairs(path:GetWaypoints()) do
local part = Instance.new("Part")
part.Material = "Neon"
part.Size = Vector3.new(0.6,0.6,0.6)
part.Position =v.Position + Vector3.new(0,2,0)
part.Anchored = true
part.CanCollide = false
part.Parent = game.Workspace.Map
part.CanTouch = false
end
end
return path
end
local function Attack(target)
local distance = (Debra.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
hum.WalkSpeed = 40
if distance > 15 then
hum:MoveTo(target.HumanoidRootPart.Position)
else
if target:FindFirstChild("Hiding") == nil then
target.Torso.Anchored = false
wait()
Debra.HumanoidRootPart.CFrame = CFrame.new(Debra.HumanoidRootPart.Position,Vector3.new(target.HumanoidRootPart.Position.X,Debra.HumanoidRootPart.Position.Y,target.HumanoidRootPart.Position.Z))
target.HumanoidRootPart.CFrame = Debra.HumanoidRootPart.CFrame * CFrame.new(0,3,-7.5)
target.HumanoidRootPart.CFrame = CFrame.new(target.HumanoidRootPart.Position,Vector3.new(Debra.HumanoidRootPart.Position.X,target.HumanoidRootPart.Position.Y,Debra.HumanoidRootPart.Position.Z))
local DKA = script.Debra
local PKA = script.Player
local animTrack1 = hum.Animator:LoadAnimation(DKA)
if debounce == false then
debounce = true
local Player = game.Players:FindFirstChild(target.Name)
local PlayerNameFolder = target.Name
local animTrack2 = target.Humanoid.Animator:LoadAnimation(PKA)
for i, v in pairs(game.Players:GetPlayerFromCharacter(target).Backpack:GetChildren()) do
if v.Name ~= "Lantern" then
v.Parent = script.Parent.Parent
v:MoveTo(target:GetPrimaryPartCFrame().p)
end
end
for i,v in pairs(target:GetChildren()) do
if v:IsA("Tool") and v.Name ~= "Lantern" then
v.Parent = workspace
v:MoveTo(target:GetPrimaryPartCFrame().p)
end
end
for i,v in pairs(target:GetDescendants()) do
if v:IsA("MeshPart") or v:IsA("Part") then
v.CanCollide = false
end
end
target.Humanoid.WalkSpeed = 0
hum.WalkSpeed = 0
Debra.HumanoidRootPart.Anchored = true
animTrack1.Priority = Enum.AnimationPriority.Action
animTrack2.Priority = Enum.AnimationPriority.Action
Ev:FireClient(Player)
animTrack2:Play()
animTrack1:Play()
wait(3)
target.Humanoid.Health = 0
animTrack1.Stopped:Wait()
Debra.HumanoidRootPart.Anchored = false
wait(1)
hum.WalkSpeed = 8
debounce = nil
local Grave = game.ReplicatedStorage.Gravestone:Clone()
Grave.Main.BillboardGui.PlayerName.Text = target.Name
Grave.Main.SurfaceGui.PlayerName.Text = target.Name
Grave.Parent = script.Parent.Parent
wait(0.1)
Grave.PrimaryPart.CFrame = CFrame.new(target.PrimaryPart.Position.X,target.PrimaryPart.Position.Y - 0.13,target.PrimaryPart.Position.Z)
Grave:PivotTo(Grave:GetPivot() * CFrame.Angles(math.rad(0), math.random(10, 350), math.rad(0)))
wait(0.1)
Grave.PrimaryPart.Anchored = false
wait(0.25)
Grave.PrimaryPart.Anchored = true
if game.ReplicatedStorage.RoundInfo.Players:FindFirstChild(PlayerNameFolder) then
game.ReplicatedStorage.RoundInfo.Players:FindFirstChild(PlayerNameFolder):Destroy()
end
end
end
end
end
local function WalkTo(destination)
local path = getPath(destination)
if path.Status == Enum.PathStatus.Success then
for i,waypoint in pairs(path:GetWaypoints()) do
path.Blocked:Connect(function()
path:Destroy()
end)
local target = findTarget()
if target and target.Humanoid.Health > 0 then
lastPos = target.HumanoidRootPart.Position
Attack(target)
break
else
if lastPos then
hum:MoveTo(lastPos)
hum.MoveToFinished:Wait()
lastPos = nil
hum.WalkSpeed = 8
break
else
hum:MoveTo(waypoint.Position)
hum.MoveToFinished:Wait()
end
end
end
else
wait(0.25)
return
end
end
local function Patrol()
local waypoints = workspace.Map.Waypoints:GetChildren()
local ranNum = math.random(1, #waypoints)
WalkTo(waypoints[ranNum])
end
while task.wait() do
Patrol()
end