Help with NPC script

I’m trying to make the pathfinding script created in this video: https://www.youtube.com/watch?v=ibvoqnG3YqI

But with my script, there’s a problem with the npc. When chasing another non-player character, it works fine, but when chasing a player’s character, it begins pausing in between waypoints (kind of like its stuttering) when it gets close to the player. After it starts doing that, it carries on even when the player has been moved further away. Anyone know what could be causing this?

This is the full script (I’m not using the animation in the video with my npc):

local PathService = game:GetService("PathfindingService")

local human = script.Parent:WaitForChild("Humanoid")
local myRoot = script.Parent:WaitForChild("Torso")

local scream = script.Parent.Ghost["Under Shirt"].scream

local Clone = script.Parent:Clone()

local function WalkAround()
	local xRand = math.random(-20, 20)
	local zRand = math.random(-20, 20)
	local goal = myRoot.Position + Vector3.new(xRand, 0, zRand)
	
	local path = PathService:CreatePath()
	path:ComputeAsync(myRoot.Position, goal)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for i, waypoint in pairs(waypoints) do
			human:MoveTo(waypoint.Position)
			local timeOut = human.MoveToFinished:Wait()
			if not timeOut then
				print("Got Stuck")
				human.Jump = true
				WalkAround()
			end
		end
	else
		print("Path Failed")
		wait(1)
		WalkAround()
	end
end

local function CheckSight(target)
	local rayCastParams = RaycastParams.new()

	rayCastParams.FilterDescendantsInstances = {workspace.Filters, script.Parent}
	rayCastParams.FilterType = Enum.RaycastFilterType.Blacklist

	local RayCast = workspace:Raycast(myRoot.Position, (target.Position - myRoot.Position).Unit * 40, rayCastParams)
	if RayCast then
		if RayCast.Instance:IsDescendantOf(target.Parent) and math.abs(RayCast.Instance.Position.Y - myRoot.Position.Y) < 3 then
			print("I can see the target")
			return true
		end
	end
	return false
end

local function findPath(target)
	local path = PathService:CreatePath()
	path:ComputeAsync(myRoot.Position, target.Position)
	local waypoints = path:GetWaypoints()
	
	if path.Status == Enum.PathStatus.Success then
		for i, waypoint in pairs(waypoints) do
			human:MoveTo(waypoint.Position)
			local timeOut = human.MoveToFinished:Wait(2)
			if not timeOut then
				print("Got Stuck")
				findPath(target)
				break
			end
			if CheckSight(target) then
				repeat
					print("Moving to the target")
					human:MoveTo(target.Position)
					wait(0.1)
					if target == nil then
						break
					elseif target.Parent == nil then
						break
					end
				until CheckSight(target) == false
				break
			end
			if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
				print("Target has moved, making new path")
				findPath(target)
				break
			end
		end
	end
end

local function findTarget()
	local dist = 200
	local target = nil
	local potentialTargets = {}
	local seeTargets = {}
	for i, v in ipairs(workspace:GetChildren()) do
		local humanoid = v:FindFirstChild("Humanoid")
		local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
		if humanoid and torso and v.Name ~= script.Parent.Name then
			if (myRoot.Position - torso.Position).magnitude < dist then
				table.insert(potentialTargets, torso)
			end
		end
	end
	if #potentialTargets > 0 then
		for i, v in ipairs(potentialTargets) do
			if CheckSight(v) then
				table.insert(seeTargets, v)
			elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
				target = v
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	if #seeTargets > 0 then
		dist = 200
		for i, v in ipairs(seeTargets) do
			if (myRoot.Position - v.Position).magnitude < dist then
				target = v
				dist = (myRoot.Position - v.Position).magnitude
			end
		end
	end
	if target then
		if math.random(1, 50) == 1 then
			scream:Play()
		end
	end
	return target
end

function main()
	local target = findTarget()
	if target ~= nil then
		findPath(target)
	else
		WalkAround()
	end
end

while wait() do
	main()
end
2 Likes

The problem might be a player being close to another player or fake player. The coded npc might struggle choosing what one to take as they can’t really see that it are 2 separated users.

2 Likes

Theres only one player in the game

1 Like