A* Pathfinding Project

Possible bug (PathInterpolator out of bounds exception)


#1

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
     AstarPath.StartPath(towards_destin);
     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
     _navAgentSeeker.StartPath(p);
     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.

Edit:
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


#2

Hi

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.