-
What do you want to achieve?
I want to make it that normally, the npc uses walkto() to walk to player WITHOUT pathfinding. There is a part that when the npc in in the part, the npc will use pathfinding, and when it is not in the part then it will stop using pathfinding and continue using moveto() -
What is the issue? Include screenshots / videos if possible!
the npc walks to the last point of the player’s location when it walks in the part and stops moving after reaching
-
What solutions have you tried so far? i asked chatgpt over 5 times:skull:
game file: ai testing.rbxl (83.4 KB) i promise it is not a virus
local NPCsFolder = game.Workspace.NPCS
local canFollowNPCs = false
local ws = game:GetService("Workspace")
local rs = game:GetService("RunService")
local ts = game:GetService("TweenService")
local pfs = game:GetService("PathfindingService")
local function getNearestTarget(npc, root)
local dist = 1000
local char
if canFollowNPCs == true then
for _, v in pairs(ws:GetChildren()) do
if v:FindFirstChild("Humanoid") and v:FindFirstChild("HumanoidRootPart") and v ~= npc then
local vHum = v:WaitForChild("Humanoid")
local vRoot = v:WaitForChild("HumanoidRootPart")
if vHum.Health > 0 then
local magnitude = (vRoot.Position - root.Position).Magnitude
if magnitude <= dist then
dist = magnitude
char = v
end
end
end
end
else
for _, player in pairs(game.Players:GetPlayers()) do
local vChar = player.Character
if vChar and vChar:FindFirstChild("Humanoid") and vChar:FindFirstChild("HumanoidRootPart") then
local vHum = vChar:WaitForChild("Humanoid")
local vRoot = vChar:WaitForChild("HumanoidRootPart")
if vHum.Health > 0 then
local magnitude = (vRoot.Position - root.Position).Magnitude
if magnitude <= dist then
dist = magnitude
char = vChar
end
end
end
end
end
return char
end
local function handleNPCBehavior(npc)
local hum = npc:FindFirstChildOfClass("Humanoid")
local root = npc.HumanoidRootPart
hum:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false)
hum:SetStateEnabled(Enum.HumanoidStateType.PlatformStanding, false)
local rs = game:GetService("RunService")
local pfs = game:GetService("PathfindingService")
local designatedAreasFolder = workspace:WaitForChild("ai_zones")
local designatedParts = {}
local usingPathfinding = npc.Configuration.ai.Value
local path
local pathUpdateInterval = 0.5 -- Recalculation time interval in seconds
-- Gather designated parts to be ignored in pathfinding
for _, part in ipairs(designatedAreasFolder:GetChildren()) do
if part:IsA("BasePart") then
table.insert(designatedParts, part)
end
end
-- Set up raycast params to ignore designated parts
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = designatedParts
-- Check if NPC is inside any designated area part
local function isInsideAnyPart(position)
for _, part in ipairs(designatedParts) do
local size = part.Size
local partPos = part.Position
local halfSize = size / 2
if (position.X > partPos.X - halfSize.X and position.X < partPos.X + halfSize.X) and
(position.Y > partPos.Y - halfSize.Y and position.Y < partPos.Y + halfSize.Y) and
(position.Z > partPos.Z - halfSize.Z and position.Z < partPos.Z + halfSize.Z) then
return true
end
end
return false
end
-- Create a path to the target position
local function createPathToTarget(targetPosition)
if path then
path:Destroy()
end
path = pfs:CreatePath({
AgentHeight = hum.HipHeight,
AgentRadius = 1.6,
AgentCanJump = true,
WaypointSpacing = 2,
FilterParams = raycastParams
})
path:ComputeAsync(root.Position, targetPosition)
return path
end
-- Follow the path continuously to the target with recalculations
local function followPathContinuously(targetRoot)
while usingPathfinding and path and path.Status == Enum.PathStatus.Complete do
for _, waypoint in ipairs(path:GetWaypoints()) do
if not usingPathfinding then break end
-- Move to each waypoint, updating path periodically
hum:MoveTo(waypoint.Position)
-- Wait for either movement or recalculation interval
local timeout = tick() + pathUpdateInterval
while hum.MoveToFinished:Wait() == false and tick() < timeout do
rs.Heartbeat:Wait()
end
-- Recalculate path if timeout reached
if tick() >= timeout then
path = createPathToTarget(targetRoot.Position)
break
end
end
end
end
-- Main loop to manage pathfinding based on designated area
rs.Heartbeat:Connect(function()
if root.Anchored == false then
root:SetNetworkOwner(nil)
end
local target = getNearestTarget(npc, root)
if target then
local targetRoot = target:WaitForChild("HumanoidRootPart")
local insideArea = isInsideAnyPart(root.Position)
if insideArea then
-- Start or continue pathfinding if inside area
if not usingPathfinding then
usingPathfinding = true
path = createPathToTarget(targetRoot.Position)
followPathContinuously(targetRoot)
end
else
-- Outside area: Move directly to player without pathfinding
usingPathfinding = false
if path then
path:Destroy()
path = nil
end
hum:MoveTo(targetRoot.Position)
end
end
end)
end
for _, npc in pairs(NPCsFolder:GetChildren()) do
if npc:IsA('Model') and npc:FindFirstChildOfClass("Humanoid") then
handleNPCBehavior(npc)
end
end
note: i will not be online for now cuz im in skool and im using vpn rn