Lerp-Path fails to start sometimes

I have a gameobject with an AI Lerp and a Seeker script attached. This is a prefab, and I use a GameObject.Instantiate to create one. Immediately after, I set the Lerp target and call “lerp.SearchPath();”, I have tried “lerp.ForceSearchPath();” as well, with no difference.

However, sometimes, like 10% of the time, seemingly randomly, the unit fails to move. As soon as another instance is created in the same place, the old one is flung out of the game area, presumably due to physics collision.

What causes the SearchPath to fail, and how do I handle this?

Actually, by manually deleting all the other instances that worked fine, I see the path exists, its just not walking the path. Why? Once it gets flung, the path is still there.

Hi

What version are you using?
Are there any path errors being reported? (make sure to enable A* Inspector -> Settings -> Path Log Mode).

That sounds odd. AILerp doesn’t use any physics at all.

Removing the Rigidbody component got rid the flinging. Not sure why I still had that as part of the object, I thought it was required for something, not sure.

Some of them still just sit at the spawn point now, stacking.

I set Settings/Debug/Path Logging to Heavy, not getting any errors, just constant reports of the path being computed and the scanning.


As a side note, is there a quick setting to make paths and the grid show up in the game window instead of just the scene window?

What version are you using?

At the top right corner of the game view window there should be a button that says ‘Gizmos’. If you click it then you will see the paths in the game view too.

3.8.8.1

There is a Beta 4.0.5
Should I update to it, or to the latest stable version?

Edit: Oh wait, thats the highest free verson, nevermind.

The AltenatePath Script has the “Wating for Apply” boolean flipped on, and previous seed/Penalty is zero, unlike the functional ones which have values set.

There is potentially a race case bug in that version that could cause it not to run.
Try to open the AILerp script, find the part of the code that looks like this

/** Starts searching for paths.
* If you override this function you should in most cases call base.Start () at the start of it.
* \see OnEnable
* \see RepeatTrySearchPath
*/
protected virtual void Start () {
	startHasRun = true;
	OnEnable();
}

/** Run at start and when reenabled.
* Starts RepeatTrySearchPath.
*
* \see Start
*/
protected virtual void OnEnable () {
	lastRepath = -9999;
	canSearchAgain = true;

	if (startHasRun) {
		// Make sure we receive callbacks when paths complete
		seeker.pathCallback += OnPathComplete;

		StartCoroutine(RepeatTrySearchPath());
	}
}

and replace it with this:

/** Starts searching for paths.
* If you override this function you should in most cases call base.Start () at the start of it.
* \see Init
* \see RepeatTrySearchPath
*/
protected virtual void Start () {
	startHasRun = true;
	Init();
}

/** Run at start and when reenabled.
* Starts RepeatTrySearchPath.
*
* \see Init
*/
protected virtual void OnEnable () {
	// Make sure we receive callbacks when paths complete
	seeker.pathCallback += OnPathComplete;

	Init();
}

void Init () {
	lastRepath = -9999;
	canSearchAgain = true;

	if (startHasRun) {
		StartCoroutine(RepeatTrySearchPath());
	}
}

Appears to have fixed it.

I might as well ask while I’m here.
I have a collider(Trigger) on an object, which detects when the GameObject (we are concerned with) enters it. Without the rigidbody, it stops registering. Not sure why.

Is there a way to call a function on path complete?

I think I would have to derive from AILerp, actually, and Override OnPath Complete.

1 Like

That’s how Unity works. Check the Unity documentation for rigidbodies and triggers. It will explain exactly that behavior.

You mean when the agent reaches the end of the path? Yes, you can override the OnTargetReached method in the AILerp class. The AILerp.targetReached property will also be true when that happens.

Is Kinematic
That fixed the whole thing,
/Ignore Physics.

Hmm. I think I will still stick with the collider though for now, might consider messing with the library later.

So, that rare bug. What exactly causes it, and how did that fix work?

What happened was that you calling SearchPath caused a path to be requested. As it happens the AILerp script does not start to listen for path-calculated callbacks until the Start method is called. So this sequence of events would play out:

  • AILerp component created
  • You called AILerp.SearchPath which started a path request
  • The path is calculated in the background by another thread
  • AstarPath.Update is called which notices that a new path has been completed and tells the Seeker component to notify any listeners that the path has been calculated, however there are currently no listeners.
  • The AILerp.Start method is called. This would tell the Seeker that it should tell the AILerp script every time a path has been calculated.

This would only happen if 1. You called SearchPath before the Start method was executed and 2. You used multithreading and the thread was fast enough to be able to calculate the path in the small amount of time between the AILerp component was created and its Start method was called.

The fix makes sure that the AILerp component starts listening for path callbacks in the OnEnable method instead.

That explains it. Running the call in the OnStart method would have also fixed it.