(5.0.3) Crash when using FleePath

Hello Aron,

I am getting this error - I cannot reproduce it every time, but it seems to happen when using the FleePath…

AssertionException: Assertion failure. Values are not equal.
Expected: 6 == 0
UnityEngine.Assertions.Assert.Fail (System.String message, System.String userMessage) (at :0)
UnityEngine.Assertions.Assert.AreEqual[T] (T expected, T actual, System.String message, System.Collections.Generic.IEqualityComparer1[T] comparer) (at <ef03b3d050364d868640c193e219b45d>:0) UnityEngine.Assertions.Assert.AreEqual[T] (T expected, T actual, System.String message) (at <ef03b3d050364d868640c193e219b45d>:0) UnityEngine.Assertions.Assert.AreEqual (System.Int32 expected, System.Int32 actual) (at <ef03b3d050364d868640c193e219b45d>:0) Pathfinding.Path.Trace (System.UInt32 fromPathNodeIndex) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/Pathfinding/Path.cs:733) Pathfinding.RandomPath.OnFoundEndNode (System.UInt32 pathNode, System.UInt32 hScore, System.UInt32 gScore) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Pathfinders/RandomPath.cs:197) Pathfinding.RandomPath.OnVisitNode (System.UInt32 pathNode, System.UInt32 hScore, System.UInt32 gScore) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Pathfinders/RandomPath.cs:220) Pathfinding.TriangleMeshNode.OpenAtPoint (Pathfinding.Path path, System.UInt32 pathNodeIndex, Pathfinding.Int3 pos, System.Int32 edge, System.UInt32 gScore) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Graphs/Nodes/TriangleMeshNode.cs:388) Pathfinding.TriangleMeshNode.Open (Pathfinding.Path path, System.UInt32 pathNodeIndex, System.UInt32 gScore) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Graphs/Nodes/TriangleMeshNode.cs:339) Pathfinding.Path.CalculateStep (System.Int64 targetTick) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/Pathfinding/Path.cs:1018) Pathfinding.Path.Pathfinding.IPathInternals.CalculateStep (System.Int64 targetTick) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/Pathfinding/Path.cs:1046) Pathfinding.PathProcessor.CalculatePathsThreaded (Pathfinding.PathHandler pathHandler, Pathfinding.BlockableChannel1+Receiver[T] receiver) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/Pathfinding/PathProcessor.cs:329)
UnityEngine.Debug:LogException(Exception)
Pathfinding.PathProcessor:CalculatePathsThreaded(PathHandler, Receiver) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/Pathfinding/PathProcessor.cs:379)
Pathfinding.<>c__DisplayClass27_0:b__0() (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/Pathfinding/PathProcessor.cs:121)
System.Threading.ThreadHelper:ThreadStart()

Here is a screenshot of the follow-up errors… say something if you need more info, then I will try to reproduce it :slight_smile:

Another crash that I had, that made the AI go full-stop … not sure if I should open another thread?

NullReferenceException: Object reference not set to an instance of an object
Pathfinding.Poly2Tri.DTSweep.FlipScanEdgeEvent (Pathfinding.Poly2Tri.DTSweepContext tcx, Pathfinding.Poly2Tri.TriangulationPoint ep, Pathfinding.Poly2Tri.TriangulationPoint eq, Pathfinding.Poly2Tri.DelaunayTriangle flipTriangle, Pathfinding.Poly2Tri.DelaunayTriangle t, Pathfinding.Poly2Tri.TriangulationPoint p) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Poly2Tri.DTSweep.FlipEdgeEvent (Pathfinding.Poly2Tri.DTSweepContext tcx, Pathfinding.Poly2Tri.TriangulationPoint ep, Pathfinding.Poly2Tri.TriangulationPoint eq, Pathfinding.Poly2Tri.DelaunayTriangle t, Pathfinding.Poly2Tri.TriangulationPoint p) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Poly2Tri.DTSweep.FlipEdgeEvent (Pathfinding.Poly2Tri.DTSweepContext tcx, Pathfinding.Poly2Tri.TriangulationPoint ep, Pathfinding.Poly2Tri.TriangulationPoint eq, Pathfinding.Poly2Tri.DelaunayTriangle t, Pathfinding.Poly2Tri.TriangulationPoint p) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Poly2Tri.DTSweep.EdgeEvent (Pathfinding.Poly2Tri.DTSweepContext tcx, Pathfinding.Poly2Tri.TriangulationPoint ep, Pathfinding.Poly2Tri.TriangulationPoint eq, Pathfinding.Poly2Tri.DelaunayTriangle triangle, Pathfinding.Poly2Tri.TriangulationPoint point) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Poly2Tri.DTSweep.EdgeEvent (Pathfinding.Poly2Tri.DTSweepContext tcx, Pathfinding.Poly2Tri.DTSweepConstraint edge, Pathfinding.Poly2Tri.AdvancingFrontNode node) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Poly2Tri.DTSweep.Sweep (Pathfinding.Poly2Tri.DTSweepContext tcx) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Poly2Tri.DTSweep.Triangulate (Pathfinding.Poly2Tri.DTSweepContext tcx) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Poly2Tri.P2T.Triangulate (Pathfinding.Poly2Tri.TriangulationContext tcx) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Poly2Tri.P2T.Triangulate (Pathfinding.Poly2Tri.TriangulationAlgorithm algorithm, Pathfinding.Poly2Tri.Triangulatable t) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Poly2Tri.P2T.Triangulate (Pathfinding.Poly2Tri.Polygon p) (at <07aca9e84ffe412bbfb50d0962eb64f2>:0)
Pathfinding.Graphs.Navmesh.TileHandler.CutPoly (Pathfinding.Int3[] verts, System.Int32[] tris, Pathfinding.Int3[] extraShape, Pathfinding.Util.GraphTransform graphTransform, Pathfinding.IntRect tiles, Pathfinding.Graphs.Navmesh.TileHandler+CutMode mode, System.Int32 perturbate) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Graphs/Navmesh/TileHandler.cs:720)
Pathfinding.Graphs.Navmesh.TileHandler+<>c__DisplayClass42_0.b__0 (Pathfinding.IWorkItemContext context, System.Boolean force) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Graphs/Navmesh/TileHandler.cs:1205)
Pathfinding.WorkItemProcessor.ProcessWorkItems (System.Boolean force, System.Boolean sendEvents) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/Misc/WorkItemProcessor.cs:339)
Pathfinding.WorkItemProcessor.ProcessWorkItemsForUpdate (System.Boolean force) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/Misc/WorkItemProcessor.cs:416)
AstarPath.PerformBlockingActions (System.Boolean force) (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/AstarPath.cs:897)
AstarPath.Update () (at ./Library/PackageCache/com.arongranberg.astar@5.0.3/Core/AstarPath.cs:880)

Hi

Would you mind posting the code for exactly how you are using the FleePath?
I suspect that you might be pooling the path incorrectly.

Sure :slight_smile:

I think I only copied this from another thread here, or from documentation…

var theGScoreToStopAt = (int)(distance * 1000f);

var path = FleePath.Construct(transform.position, fleeFrom, theGScoreToStopAt);
path.aimStrength = aimStrength;
path.spread = (int)Mathf.Max(4000, distance);

constraint.graphMask = seeker.graphMask;
path.nnConstraint = constraint;

seeker.StartPath(path, SetFleePath);

And your SetFleePath code?

I am overriding RichAI, so this is what it looks like, calling the RichAI’s SetPath method:

  private void SetFleePath(Path p)
  {
  	SetPath(p, true);
  }

Also:

Just read the documentation, I misunderstood the “spread” variable, will change that to 4000 again … doesn’t make sense to use the actual distance, I think :slight_smile: :roll_eyes:

Hi

Ok.
Since 5.0, it is strongly recommended to just call ai.SetPath(path) instead of going via the Seeker.

So instead of you calling

seeker.StartPath(path, SetFleePath);

just call

ai.SetPath(path);

Doing it like you do shouldn’t have caused the error. I even tried to replicate it to see if there was any recent bug, but it works correctly for me. But in any case, it’s the better way to go about it. Would you mind trying to see if that solves it?
See Upgrade Guide - A* Pathfinding Project for more details

1 Like

I changed that, also upgraded to 5.0.4 … the error is still occuring :frowning:

FYI: Not sure if that’s worth the notion but I noticed that A* Pathfinding has a dependency to Burst 1.8.3 → Package Manager only offers me 1.8.13.

Would you mind posting your complete class that overrides the RichAI?

That’s fine. It’s compatible with newer versions too.

Here you are :slight_smile:

using Pathfinding;
using UnityEngine;

namespace LaserKnights.Units.Ai
{
    public class MovementAgent : RichAI
    {
        public event System.Action<Path> OnPathFound;

		private NNConstraint constraint = NNConstraint.Walkable;

		public Vector2 GetDesiredMovement01()
		{
			if (Mathf.Approximately(maxSpeed, 0f))
			{
				return Vector2_Const.Zero;
			}

			return desiredVelocity.GetXZ() / maxSpeed;
		}

		protected override void Awake()
		{
			base.Awake();

			constraint.distanceMetric = DistanceMetric.ClosestAsSeenFromAboveSoft();
		}

		protected override void OnEnable()
		{
			base.OnEnable();

			Reset();
		}

		public override void Teleport(Vector3 newPosition, bool clearPath = true)
		{
			FindComponents();

			base.Teleport(ClampPositionToGraph(newPosition), clearPath);
		}

		public void Flee(Vector3 fleeFrom, float distance, float aimStrength = 1)
        {
			if (seeker == null)
			{
				return;
			}

			var theGScoreToStopAt = (int)(distance * 1000f);

            var path = FleePath.Construct(transform.position, fleeFrom, theGScoreToStopAt);
            path.aimStrength = aimStrength;
            path.spread = 4000;
			
			constraint.graphMask = seeker.graphMask;
			path.nnConstraint = constraint;

			SetPath(path, true);
		}

		protected override void OnPathComplete(Path p)																				    
		{
			base.OnPathComplete(p);

			if (p.IsDone())
			{
				OnPathFound?.Invoke(p);
			}
		}
	}
}

Hmm. Well, nothing looks particularly strange there.

Would it be possible for you to share an example scene which shows the issue? That would help a lot in debugging the issue.

I will try to… but that will take some time … too many dependencies, too many other stuff going on… will have to throw out everything, and then hope that the same can still be reproduced…

We will see :roll_eyes:

Ok, just as I expected… I cannot reproduce it in an example scene…

Had a look into the actual A* code… what is line 733 in Path.cs actually doing?

UnityEngine.Assertions.Assert.AreEqual(0, path.Count);

I removed it, now the error seems to not occur anymore…

Don’t know if that helps :smiley:

Edit: just to say that - I know what asserts do :wink: just not sure why you are asserting there?

Edit 2: can’t you just clear the path list?

Just to be sure, for the test project I

  • used the same A* Pathfinding settings
  • used the same level geometry (in case something is broken there)
  • used the same character controller (Kinematic Character Controller)
  • used the same script execution order
  • added all plugins I have in my main project

I cannot reproduce that bug…

I also checked my main project - I thought maybe I am sending multiple FleePath request per frame… that is also not the problem: FleePath will be called every ~2-3 frames, but not within one frame.

Also checked the initialisation of A* Pathfinding: if I start a level in the Unity editor, I instantiate the A* Pathfinding before starting the editor… thought that could be an issue, so I placed the A* Pathfinding object in the scene - it also didn’t change anything… :frowning:

For the moment I am replacing the “assert” line with

path.Clear();

Sorry for that, but it currently totally blocks me, and I want to continue development :grin:
Will have to make a copy of A*, so that Unity doesn’t delete the change…

But maybe we can find a real solution for that?

Hi

The reason I assert there, and don’t just clear the list, is that the list should be cleared at this point. If it’s not cleared, it indicates a signficant bug, and possibly a race condition somewhere else.

Oof, that’s annoying.

I’d like to Debug.Log my way out of this… I tried to find out where exactly the “path” list is filled and cleared, currently I am at the ListPool.cs

But I still cannot find the position where the list is cleared… I think that would help, finding out who adds positons, who clears it, and by logging, I might find out where the path is “not cleared” but given back to the pool…

Any tips where the clear() should happen?

Hi

The path list is cleared (or rather, a new empty list is taken from the pool) in the Path.Reset method.

Try to check if the Trace method is being called twice for some reason.

While trying to log the “Trace()” calls, I noticed that the error only happens when multiple enemies are around… and I am not sure about my initial idea of why this happens… it has either nothing to do with FleePath, or it is happening after or during FleePath has been calculated.

See the screenshot:

Before the 2 “Trace” calls I marked red, it is only being called once before a different “state” (from my code) is started.

Then with the 2 Trace calls, the error is being called… here is the stack trace of the 2 Trace methods:

Trace!
UnityEngine.Debug:Log (object)
Pathfinding.Path:Trace (uint) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/Path.cs:718)
Pathfinding.RandomPath:OnFoundEndNode (uint,uint,uint) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Pathfinders/RandomPath.cs:197)
Pathfinding.RandomPath:OnVisitNode (uint,uint,uint) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Pathfinders/RandomPath.cs:220)
Pathfinding.TriangleMeshNode:OpenAtPoint (Pathfinding.Path,uint,Pathfinding.Int3,int,uint) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Graphs/Nodes/TriangleMeshNode.cs:388)
Pathfinding.TriangleMeshNode:Open (Pathfinding.Path,uint,uint) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Graphs/Nodes/TriangleMeshNode.cs:339)
Pathfinding.Path:CalculateStep (long) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/Path.cs:1022)
Pathfinding.Path:Pathfinding.IPathInternals.CalculateStep (long) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/Path.cs:1050)
Pathfinding.PathProcessor:CalculatePathsThreaded (Pathfinding.PathHandler,Pathfinding.BlockableChannel`1/Receiver<Pathfinding.Path>) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/PathProcessor.cs:329)
Pathfinding.PathProcessor/<>c__DisplayClass27_0:<StartThreads>b__0 () (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/PathProcessor.cs:121)
System.Threading.ThreadHelper:ThreadStart ()
Trace!
UnityEngine.Debug:Log (object)
Pathfinding.Path:Trace (uint) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/Path.cs:718)
Pathfinding.ABPath:OnFoundEndNode (uint,uint,uint) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Pathfinders/ABPath.cs:485)
Pathfinding.Path:CalculateStep (long) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/Path.cs:1010)
Pathfinding.Path:Pathfinding.IPathInternals.CalculateStep (long) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/Path.cs:1050)
Pathfinding.PathProcessor:CalculatePathsThreaded (Pathfinding.PathHandler,Pathfinding.BlockableChannel`1/Receiver<Pathfinding.Path>) (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/PathProcessor.cs:329)
Pathfinding.PathProcessor/<>c__DisplayClass27_0:<StartThreads>b__0 () (at ./Library/PackageCache/com.arongranberg.astar@5.0.4/Core/Pathfinding/PathProcessor.cs:121)
System.Threading.ThreadHelper:ThreadStart ()

Try logging something like:

Debug.Log(this.pathID + " " + this.GetType().Name + " Trace");

I think a lot of those are not from a RandomPath.