In this lesson, you will learn how to maintain high frame rates while managing hundreds of NPCs by decoupling state logic from Update() loops and implementing staggered execution.
When you have many NPCs running individual Update() methods, you create a "death by a thousand cuts" scenario where the CPU struggles to process state logic for every character simultaneously every single frame. To optimize this, we shift from a push-based model (where every NPC pulls processing power every frame) to a throttled, data-oriented approach.
Implementing Time-Sliced Updates
Instead of every StateMachine running its logic in Update(), we use a manager that distributes the workload over several frames. By using a modulo operator against the Time.frameCount, we can force specific groups of NPCs to update only on specific frames, effectively spreading the CPU load.
public class NPCManager : MonoBehaviour
{
private List<NPCStateMachine> npcs;
public int updateSpread = 5; // NPCs processed over 5 frames
void Update()
{
for (int i = 0; i < npcs.Count; i++)
{
// Only update if this NPC's turn in the rotation matches the current frame
if (i % updateSpread == Time.frameCount % updateSpread)
{
npcs[i].Tick();
}
}
}
}
Data-Oriented State Logic
To further increase performance, move state data into simple structs or plain C# classes. By separating the data (current state, target destination, health) from the logic (how to transition), you ensure that your cache-local operations are as efficient as possible. If an NPC is far from the camera or "inactive," we can completely bypass their Tick() call, saving precious milliseconds.
By combining time-slicing with a centralized manager, you stop NPCs from fighting for resources. You effectively move from "every NPC thinks every frame" to "every NPC thinks when it is their turn," which scales significantly better as your population grows.
Key Takeaway: Distribute NPC state processing across multiple frames using time-slicing to prevent CPU spikes and ensure smooth performance as your crowd density increases.