Reminder to self. Here’s some code from state-based navigation logic. It’s in Update(), using a case statement on the state variable. Basically. we’ve got a destination, so set it, and go to the next state.
// Set up navmesh.
_navMeshAgent.speed = speed;
// Set up the animator.
_animator.SetFloat(animationParameter, _navMeshAgent.speed);
// Start the navmesh.
_navMeshAgent.destination = _collectibleBeingFetched.transform.position;
_navMeshAgent.isStopped = false;
state = CollectibleCarrierState.MovingToCollectible;
break;
case CollectibleCarrierState.MovingToCollectible:
// Are we there yet?
if (_navMeshAgent.remainingDistance <= collectionPointStoppingDistance)
{
Because of the break after setting the new state, the MovingToCollectible code doesn’t run until the next frame.
It worked most of the time, but sometimes, _navMeshAgent.remainingDistance would be zero. Ack!
The problem was the agent can take more than one frame to work out a path. Makes sense. For a long path calculation, you don’t want to block the main thread. Break the path computation up over a few frames.
My logic didn’t allow for that. To fix, check hasPath before seeing if we’re there yet:
_navMeshAgent.destination = _collectibleBeingFetched.transform.position;
_navMeshAgent.isStopped = false;
state = CollectibleCarrierState.MovingToCollectible;
break;
case CollectibleCarrierState.MovingToCollectible:
// Have a path yet? It can take more than one frame.
if (!_navMeshAgent.hasPath)
{
break;
}
// Are we there yet?
if (_navMeshAgent.remainingDistance <= collectionPointStoppingDistance)
{