N.P.C. is stuck

Hello and thank you for seeing this, I will have a video below showcasing my problem and below that my script. If you have any ideas they are appreciated:

The ones is the script updating the pathfinding.

Before you read my script, please keep in mind that it is on a local script.

-- Services
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")

-- Constants
local ATTACK_DISTANCE = 5.5
local WAIT_TIME_BEFORE_PATROL = 7
local WAYPOINT_CHECK_INTERVAL = 0.1

-- Variables
local player = Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local enemy = nil
local waypointsFolder = game.Workspace:FindFirstChild("Waypoints")

repeat
	task.wait(0.1)
until game.Workspace:FindFirstChild("Enemy")

enemy = game.Workspace:FindFirstChild("Enemy")

-- Animations and Sounds
local walkAnim = enemy:WaitForChild("Humanoid"):LoadAnimation(script.WalkAnim)
local attackAnim = enemy.Humanoid:LoadAnimation(script.AttackAnim)
local walkSound = script.WalkSound
local attackSound = script.AttackSound

-- Pathfinding parameters
local pathParams = {
	AgentHeight = 5,
	AgentRadius = 3,
	AgentCanJump = false
}

-- Wait until enemy and waypoints are loaded
repeat
	task.wait(WAYPOINT_CHECK_INTERVAL)
	enemy = game.Workspace:FindFirstChild("Enemy")
until enemy and waypointsFolder and #waypointsFolder:GetChildren() > 0

-- Functions
local function CheckForCharacter(char)
	local rayOrigin = enemy:FindFirstChild("HumanoidRootPart").Position
	local rayDirection = (char.HumanoidRootPart.Position - rayOrigin).Unit * 40
	local raycastResult = workspace:Raycast(rayOrigin, rayDirection, RaycastParams.new())
	
	if raycastResult then
		local raycastInstance = raycastResult.Instance
		
		if raycastInstance:IsDescendantOf(char) then
			return true
		end
	else
		return false
	end
end

local function FindNearestPlayers()
	local players = Players:GetPlayers()
	local nearestPlayer = nil
	local maxDistance = 40
	
	for _, player in pairs(players) do
		if player.Character ~= nil then
			local targetCharacter = player.Character
			local distance = (enemy.HumanoidRootPart.Position - targetCharacter.HumanoidRootPart.Position).Magnitude
			
			if distance < maxDistance and CheckForCharacter(targetCharacter) then
				nearestPlayer = targetCharacter
				maxDistance = distance
			end
		end
	end
	
	return nearestPlayer
end

local function CalculatePath(destination)
	local path = PathfindingService:CreatePath(pathParams)
	path:ComputeAsync(enemy.HumanoidRootPart.Position, destination)
	return path
end

local function Attack(char)
	local distance = (enemy.HumanoidRootPart.Position - char.HumanoidRootPart.Position).Magnitude
	
	if distance > 5 then
		local path = CalculatePath(char.HumanoidRootPart.Position)
		if path.Status == Enum.PathStatus.Success then
			if not walkSound.Playing then
				walkAnim:Play()
				walkSound:Play()
			end
		end
	else
		walkSound:Stop()
		walkAnim:Stop()
		attackAnim:Play()
		attackSound:Play()
		task.wait(0.7)
		char.Humanoid.Health = 0
	end
end

local function WalkToDesination(destination)
	local path = CalculatePath(destination)
	
	if path.Status == Enum.PathStatus.Success then
		if not walkSound.Playing then
			walkAnim:Play()
			walkSound:Play()
		end
		for _, waypoint in pairs(path:GetWaypoints()) do
			local nearestPlayer = FindNearestPlayers()
			if nearestPlayer then
				Attack(nearestPlayer)
				break
			else
				enemy.Humanoid:MoveTo(waypoint.Position)
				enemy.Humanoid.MoveToFinished:Wait()
			end
		end
	else
		enemy.Humanoid:MoveTo(destination - (enemy.HumanoidRootPart.CFrame.LookVector * 10))
	end
end

local function Patrol()
	local waypoints = workspace.Waypoints:GetChildren()
	if #waypoints > 0 then
		local randomNumber = math.random(1, #waypoints)
		
		WalkToDesination(waypoints[randomNumber].Position)
	end
end

-- Start patrol after initial wait
task.wait(WAIT_TIME_BEFORE_PATROL)
Patrol()

-- Check for enemy and waypoints continuously
while true do
	repeat
		task.wait(WAYPOINT_CHECK_INTERVAL)
		enemy = game.Workspace:FindFirstChild("Enemy")
	until enemy

	repeat
		task.wait(WAYPOINT_CHECK_INTERVAL)
	until #waypointsFolder:GetChildren() > 0

	task.wait(WAIT_TIME_BEFORE_PATROL)  -- Wait before starting patrol again
	while true do
		print(1)
		Patrol()
		task.wait(0.1)
	end
end

Thank you, your help is appreciated! :grin:

1 Like

Here is the game link:

Game Link!

Try unachoring HumanoidRootPart. Most cases that NPCs doesn’t move because their HumanoidRootPart is anchored.

2 Likes

Ye try that

1 Like

Thank you for responding, but it is unanchored. However the problem is still there. I know the video did not show this but once the player leaves it works just fine, until it sees the player again, before it glitches out again.

Rightclick the model, Click “Expand all” And swipe over ALL of the things, Then go to properties and slide down until you find “Anchored” And click it until the icon is blank.
that should help! (cuz it could be that an accessory was anchored)

1 Like

Thank you again, but the problem is still there, although it did help :slight_smile:

1 Like

when im checking ur game tru ur link everything is fine except for the monster that can’t find the player and goes into walls. U updated a game?

1 Like

Just my opinion but it might be cause its infinitely calculating the position of the character and it just glitches out and if you have multiple functions piling up it might be glitchy.

1 Like

Also why are you moving it on a local script?

1 Like

No, but thank you! Do you have any ideas though?

Since all of my players are going to have their own maze, I need the A.I. to work locally! :slight_smile:

Have you tried print debugging by any chance?

For example, you can put a few prints in your loop which iterates over path:GetWayPoints(), I’d place a print at the top (inside of the loop), and then I’d place one to see if it is finding a nearby player, and then one above enemy.Humanoid:MoveTo().

1 Like

Hello, I have found the problem, I just do not know the solution. It continues updating to find the player however it just goes back to where it is when it gets updated. Do you have any thoughts?

Sorry for the delay, went to eat. Can you explain what you mean further? If you show me your prints and tell me what the result is, I could probably figure it out for myself without any further explanation.

1 Like

Hello, thank you for your help and I managed to fix it myself.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.