Need help on improving npc behavior

I have a really bareboned NPC system right now that basically finds the closest player and uses dot produce and raycast to check if the npc can “properly” see the npc which is all in the loop called findnearestplayer. I really new to pathfinding and using humanoid:moveto(waypoint.position) makes it very delayed and robotic. Are there anyways that I can improve the responsiveness of the NPC? I’ve considered just making the loop with delay or using runservice but I’m worried about tanking the performance.

local function CreatePath(PlayerPosition) 
	path:ComputeAsync(Model.PrimaryPart.Position, PlayerPosition)
end

local function PathFindToPlayer()
	if CloneRadius then --Dont worry about this ignore pls
		CloneRadius:Destroy()
		RoamingDebonuce = false
	end
	local PlayerCharacter = Target.Character or Target.CharacterAdded:Wait()
	local PlayerPosition = PlayerCharacter:WaitForChild("HumanoidRootPart").Position
	local Humanoid = Model:FindFirstChild("Humanoid")

	local success, errormessage = pcall(function()
		CreatePath(PlayerPosition)
	end)
		
	if success and path.Status == Enum.PathStatus.Success then --Npc walks to every waypoint
		local waypoints = path:GetWaypoints()
		for i, waypoint in ipairs(waypoints) do
			if waypoint.Action == Enum.PathWaypointAction.Jump then
				Model.Humanoid.Jump = true
			end
			Humanoid:MoveTo(waypoint.Position)
			WalkAnimation:Play()
		end
			
		if (Model.PrimaryPart.Position - PlayerPosition).Magnitude <= AttackRange then --Separate logic for this 
			repeat
				Attack()
				task.wait(ATTACKCOOLDOWN)
				Combo += 1 
				print(Combo)
			until not Attack() or Combo == 4 
			AttackDebounce = true
			task.delay(M1COOLDOWNRESET, function()
				AttackDebounce = false
				Combo = 1
			end) 
		end --If npc is close to player then it will attack 
			
		if (Model.PrimaryPart.Position - PlayerPosition).Magnitude >= AGGRORANGE then
			Target = nil 
			path:Destroy()
		end
	else
		print("PATH UNSUCCESSFUL")
	end
end

Model.Humanoid.Died:Connect(function() --Ideas, bodyragdolls on floor and despawns after a bit and some vfx effect for player maybe idk. 
	Debris:AddItem(Model, 2)
end)

task.spawn(function()
	while true do
		if not Target then 
			FindNearestPlayer()
		else
			PathFindToPlayer()
		end
		task.wait(1)
	end
end)

aftorcalling a moveto to the waypoint, I do this check

origin = where you pathfinding from , and a part
waypoint - pathfinding waypont

repeat
								task.wait()
							until (origin.Position-Vector3.new(0,0,0)-waypoint.Position).Magnitude<=6 
1 Like

oooh do you also use a loop to calculate the path if so, how often?

well, first I check if the NPC can ray to the player, if so, it uses moveto on the players position. But if it can’t see the player, I create a new path for it to go every time I move it in a loop. And when it sees the player, it sets a variable in my scripts to false to stop the pathfinding, and that code I gave you. Then it goes back to following the player since it can see the plauyer.

I do this every .05 seconds

1 Like