How to make this pathfinding system smoother?

My issue is that it does the move function then checks for fruits around so if there are no fruits it just kinda of turns side to side or shakes then goes back to moving. It’s not a big deal but I don’t want it to be something small that can be easily fixed and I didn’t try and get answers. If you have any suggestions to change the script, I will try them to see if they work, thank you!

local PathfindingService = game:GetService("PathfindingService")

-- Variables for the zombie, its humanoid, and destination
local character = script.Parent
local humanoid = character.Humanoid
local destination 

local pathParams = {["AgentRadius"] = 6, ["AgentHeight"] = 5, ["AgentCanJump"] = false}

-- Create the path object
local path = PathfindingService:CreatePath(pathParams)

-- Variables to store waypoints table and zombie's current waypoint
local waypoints
local currentWaypointIndex

local function followPath(destinationObject)
	-- Compute and check the path
	path:ComputeAsync(character.HumanoidRootPart.Position, destinationObject)
	-- Empty waypoints table after each new path computation
	waypoints = {}
	
	if path.Status == Enum.PathStatus.Success then
		-- Get the path waypoints and start zombie walking
		waypoints = path:GetWaypoints()
		-- Move to first waypoint
		currentWaypointIndex = 1
		humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
	else
		-- Error (path not found); stop humanoid
		humanoid:MoveTo(character.HumanoidRootPart.Position)
	end
end

local function onWaypointReached(reached)
	if reached and currentWaypointIndex < #waypoints then
		currentWaypointIndex = currentWaypointIndex + 1
		humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
	end
end

local function onPathBlocked(blockedWaypointIndex)
	-- Check if the obstacle is further down the path
	if blockedWaypointIndex > currentWaypointIndex then
		-- Call function to re-compute the path
		followPath(destination)
	end
end

-- Connect 'Blocked' event to the 'onPathBlocked' function
path.Blocked:Connect(onPathBlocked)

-- Connect 'MoveToFinished' event to the 'onWaypointReached' function
humanoid.MoveToFinished:Connect(onWaypointReached)

local range = 50

local function WalkAround()
	destination = Vector3.new(script.Parent.HumanoidRootPart.Position.X + math.random(-30, 30), script.Parent.HumanoidRootPart.Position.Y, script.Parent.HumanoidRootPart.Position.Y + math.random(-30, 30))
	followPath(destination)
end

local function FindFruit()
	for _, fruit in pairs(game.Workspace:GetChildren()) do
		if fruit:FindFirstChild("Fruit") then
			local distance = (script.Parent.HumanoidRootPart.Position - fruit.Position).magnitude
			if distance <= range then
				destination = fruit.Position
				followPath(destination)
			end
		end
	end	
end

while wait(2,8) do
        WalkAround()
	FindFruit()
end

Perhaps you could scatter random transparent parts around your game world. Then if the script fails to find a fruit in range, you could target a random part instead.

For example

local roamingparts= {workspace.part1, workspace.part2}

for _, fruit in pairs(game.Workspace:GetChildren()) do
	if fruit:FindFirstChild("Fruit") then
		local distance = (script.Parent.HumanoidRootPart.Position - fruit.Position).magnitude
		if distance <= range then
			destination = fruit.Position
		end
	else
		destination = roamingparts[math.random(1, #roamingparts)]
	end
	followPath(destination)
end

By using a random part, it would also ensure your NPC doesn’t stay in the same part of the game world all the time.