NavMesh Agent AI and Resource Gathering Refactor

Over the past couple of days I have rewritten nearly every part of my previous project.  It worked and served as a good basis, but there were many improvements that need to be done.  I busted out my trusty mini-whiteboard and began to rework the job process.

White Board Refactor
One whiteboarding of the cycle of the AI.

I bought this whiteboard for school and use it almost every day.  It’s a great tool to have to quickly map out a function or a process.

Initially, the state of the Agent was being checked in the Update() function.  This fine to get it working and to test the basic functionality, but I knew that eventually it would need to be moved out of it because having 100+ AIs having their state checked every update would be unnecessarily taxing on the system.

I went with an event action system that when the state needed to be changed, a private event would be invoked with the state change.  

OnAgentStateChange?.Invoke(AgentState.MovingToNode); 

Currently, I track the previous state of the AI to help with the state navigation but I am trying to find a way to eliminate having to rely on it.  I’ve set the state before moving so that I can use the same move function and not have one for each type of movement (to a node, to a container, ect…)

Handling the State Change

private void HandleOnAgentStateChange(AgentState mState) {
        state = mState;
        switch (mState) {
            case AgentState.Idle:
                StartCoroutine(AgentIdle());
                return;
            case AgentState.Rest:
                StartCoroutine(AgentRest());
                return;
            case AgentState.MovingToNode:
                lastState = AgentState.Working;
                StartCoroutine(MoveToNode(jobNode));
                return;
            case AgentState.Working:
                DoWork();
                return;
            case AgentState.MovingToTarget:
                lastState = AgentState.Delivering;
                StartCoroutine(MoveToNode(agentJob.JobWorkPlace.PrefabAccessPoints));
                return;
            case AgentState.Delivering:
                DeliverItems();
                lastState = AgentState.Idle;
                OnAgentStateChange?.Invoke(AgentState.Idle);
                return;
            default:
                return;
        }
    } 

With moving the state check out of the update, I needed a way for the AI to execute each state’s task.  I ended up using a few Unity Coroutines.  When looking at different examples of NavMesh Agents and how others implement a similar system as this seems to be some debate over the use of them.  I am happy with what I came up with and it seems to be working and performing well.  We will see how well it scales.

Improved Gathering AI
Improvements made to the AI System

You can follow this project on GitHub.

Unity NavMesh Agent AI Update