Possible bug (PathInterpolator out of bounds exception)

Hey Aron, I might have found a bug:

What I am doing:

I am using a Seeker, AIpath, Funnel modifier.
Spawning a creature, then trying to move it via my coroutine throws an error.

This first coroutine is where error is thrown:

IEnumerator moveCrtn(){
   Vector3 wantedPos_ai;
   Quaternion wantedRot_ai;
   //how the ai wants to move:         (throws the error here):
   _navAgent.MovementUpdate( Time.deltaTime,  out wantedPos_ai,  out wantedRot_ai );

I have 2 coroutines working: 1 is movement (shown above) runs separatelly. The other coroutine is the path-generating one, which gets called every N seconds from my Update_Coroutine().

this coroutine works:

IEnumerator MakesPaths_OK(){
     // Construct a path TOWARDS the "destination", and see if too far.
     ABPath towards_destin = ABPath.Construct(transform.position,  _destination);
      owards_destin.nnConstraint.tags = NavTagMasks.playerWalkable; //only allow to walk on this tag
     yield return towards_destin.WaitForPath();
     _navAgentSeeker.PostProcess( towards_destin );
     _navAgent.SetPath( towards_destin );//NOTICE: NAV AGENT, NOT SEEKER
IEnumerator makesPath_thatWillCauseError_duringMove(){
      //make the creature pause in place before seaching a new path:
     float pause = Random.Range(_wander_onPathFinishedPause.x,  _wander_onPathFinishedPause.y);
     yield return new WaitForSeconds(  pause );//make the monster pause before 
     //search for a new path:
     float rndAngle = Random.Range(-180, 180);
     float rndDist  = Random.Range(1, _wanderMaxDist);

     // NOTICE -don't assign to _targetLocation, but to destionation.
     // That's because we wish to keep running around the same point, without gradually shifting it.
     Vector3 destination  = _destination + Quaternion.Euler(0, rndAngle, 0)*Vector3.forward*rndDist;
     ABPath p = ABPath.Construct(transform.position,  destination);
     p.nnConstraint.tags = NavTagMasks.playerWalkable; //only allow to walk on this tag
     yield return p.WaitForPath();
     _navAgentSeeker.PostProcess( p );

      //NOTICE - DIDN'T SetPath explicitly for _navAgent, only started on seeker (should be done automatically though anyway)

     _MakePath_crtn = null;

The actual Error:

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.

Parameter name: index
System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at :0)
System.ThrowHelper.ThrowArgumentOutOfRangeException () (at :0)
System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at :0)
Pathfinding.Util.PathInterpolator.MoveToCircleIntersection2D (UnityEngine.Vector3 circleCenter3D, System.Single radius, Pathfinding.Util.IMovementPlane transform) (at Assets/AstarPathfindingProject/Core/Misc/PathInterpolator.cs:180)
Pathfinding.AIPath.MovementUpdateInternal (System.Single deltaTime, UnityEngine.Vector3& nextPosition, UnityEngine.Quaternion& nextRotation) (at Assets/AstarPathfindingProject/Core/AI/AIPath.cs:337)
Pathfinding.AIBase.MovementUpdate (System.Single deltaTime, UnityEngine.Vector3& nextPosition, UnityEngine.Quaternion& nextRotation) (at Assets/AstarPathfindingProject/Core/AI/AIBase.cs:403)
MonsterCharacters.WanderChaseFlee_MonsterLoco.Move_or_RotateIfStationary () (at Assets/Gameplay Scripts and Assets/Character-related scripts/EnemyCharacters/Basic Locomotion/WanderChaseFlee_MonsterLoco.cs:377)
MonsterCharacters.WanderChaseFlee_MonsterLoco+<Movement_crtn>d__37.MoveNext () (at Assets/Gameplay Scripts and Assets/Character-related scripts/EnemyCharacters/Basic Locomotion/WanderChaseFlee_MonsterLoco.cs:364)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Scripting/Coroutines.cs:17)

Trying to debug:

Putting a breakpoint on that problematic line (with condition of out of bounds) shows that ‘path.Count’ is 0. This is very weird, because that interpolater received its path before, a path whose count was 2. I know this is true because I modified ‘PathInterpolator::SetPath()’ to copy the count of incoming path into my debug variable. Or set it to -3 if incoming path was null.

When this breakpoint is hit, ‘path.Count’ is zero but my debug variable is showing 2.

So, something keeps pointing to the ‘protected PathInterpolator::path’ list, and is clearing it externally.

When instantiating a creature, I disable its gameObject on the same frame (…or maybe on the next frame?) and show it only few seconds later.

using version 4.2.5 pro


I’m not sure if this is the issue, but one thing that I notice is that you call seeker.PostProcess with a path that was started using seeker.StartPath. When the Seeker calculates the path itself it will already do all the post-processing automatically. When you wait for the path to be calculated and then call PostProcess you will be modifying the path that has already been given to the AIPath script.

1 Like