Course contentsShow
← Unity Game Development
Lesson 524 of 8288. Artificial IntelligenceFree lesson

Optimizing State Machine Performance for Multiple NPCs

Apply data-oriented patterns and update throttling techniques to manage many active state machines simultaneously without impacting the overall frame rate.

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.