Temporarily Disable AI


#1

Hi Aron,

I’ve scoured this forum and tried a few examples but to no avail. So going to defer to the experts here.

We are using your api for a hybrid RTS military style game. The game pieces move on a grid using the simplest A* methods. We aren’t doing anything fancy - your api has been fantastic for this using the most basic setup. Our grid board selection tiles match the AI grid size exactly so the path nodes fall center of each tile. Obstacles such as houses and bushes are marked unwalkable; however there are a couple game pieces that can occupy houses and vehicles such as infantry. Occupying vehicles isn’t a problem since they’re on the AI grid, but houses are off the AI grid.

How it works is when the player moves infantry into a house I get the nearest tile to the house to set the path then OnDestinationReached() I want to disable the AI temporarily and position the infantry at the center of the house (off grid) then when the player is ready to leave the house re-enable the ai so the infantry can move to a nearby tile. All this works to some extent but the infantry never take the house position even after I disable seeking and canmove in the AIPath script. They are clamped to the last node in the path.

So my question is how can I temporarily disable the aiPath for this game piece so that the infantry items can “occupy” the center of the house off grid. I also tried disabling the aiPath script altogether and it still won’t move the piece.

I know that I could set the houses as walkable with a high value, but I don’t want to rework my grid setup because doing that would have other consequences I don’t want to deal with right now.

Thanks in advance.

We have some early test demo vids on YT - you can get a sense of the game. Particularly at mark 32 where the infantry is being moved around and occupies a vehicle.


#2

Hi

Are you using any other components on the characters that could potentially interfere? If you disable the whole AIPath component then it shouldn’t still be clamping the position to the grid.


#3

Wow, that was fast. No, I am only using the seeker and AIpath, nothing else. So AIPath.canMove = false and AIPath.canSearch = false should allow me to move the game piece manually? If that’s the case I may have a logic error somewhere…just can’t find it.

FWIW I am using v4.1.11


#4

Hi

Yes, that’s right (I even verified it just now in an example scene, just to make sure I hadn’t introduced a bug recently or something).
Are you saying you are not able to move the piece at all? That sounds odd, when using the AIPath script it should be possible to move it around manually all the time (even though it will of course try to get back to where it wants to be).


#5

No it won’t move off of the last node to the house position when OnDestination is executed where I am disabling the AIPath then manually setting the transform.position. However, you’ve confirmed the way I thought how the AI scripts are supposed to worked, so it may be a logic error in the code somewhere. Let me keep pounding on it. And if I find the solution I’ll post back for the sake of others looking for help.

Thanks Aron, this api is fantastic!


#6

Hi

Ah, you are setting that in the OnDestinationReached method. That might be a problem. I think that callback runs before the movement of the agent, so the agent will override the movement later in that frame because it was already running the movement code when you disabled the component.

I would recommend that you use the ai.reachedDestination property instead and check for that in another script. That will work better I think.
The reachedDestination property only exists in 4.2 and up though, but in your version you can use ai.reachedEndOfPath instead which is similar, but it has some gotchas which are listed in the docs (which are the same as the OnDestinationReached method, I have started to discourage use of the OnDestinationReached method as well to reduce the need for people to subclass the AIPath script).

I’m glad you like the API :slight_smile: If you feel like supporting the package even more, a rating and/or review in the asset store goes a long way :slight_smile:


#7

Okay, so I stepped through the code in Visual Studio and it looks like MovementUpdate is being executed after the OnDestinationReached() code which is resetting the position after I manually set it. I believe I have the end reached distance at 0.2 and slowdown distance at 2. I suspect it is triggering the OnDestinationReached and then doing some final clean up in MovementUpdate()

Specifically, in AIPath.MovementUpdateInternal() line 312

			// Set how much the agent wants to move during this frame
			var delta2D = lastDeltaPosition = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);
			**nextPosition = currentPosition + movementPlane.ToWorld(delta2D, verticalVelocity * lastDeltaTime);**
			CalculateNextRotation(slowdown, out nextRotation);

So as I suspected this may be a frame update issue that I have to work around.


#8

Yep. See my last post (think I wrote it at the same time as you).


#9

Haha, You’re too quick.

Okay, thanks for the help. That makes sense. I have some ideas on how to handle this without updating.

And yes, I will recommend it on the store.


#10

For those who may have this issue I fixed it by setting the position using a coroutine that delays the manual setting of the position after the AiPath is finished cleaning up. I could do it other ways and may change it but for now it works and I can move forward.


#11

Sorry for the bump, but I just wanted to chime in as I’ve had the exact same problem and this thread kind of helped me. In my case, I’m also overriding OnDestinationReached and resolve a TaskCompletitionSource (to allow async/await with the pathfinding). In the end, I’ve had to do something similar to what @Dman was doing - made a Coroutine, wait a frame, and then resolve the task. It would be nice if I could somehow get rid of that Coroutine.

I’ve got the opposite problem as well though: I’m moving the agent manually, then enable the AI, and it seems to snap back to the last known location. In my case, I have a checkpoint between two completely separated areas of the graph. I have some custom logic running which walks to one side of the checkpoint, does some animations and other stuff, then moves the agent to the other side and gives it a new destination. The workaround that seems to work here is the same: Move the agent, wait a frame, enable the AI. I’m not sure if I can do this with a graph connection (as it would require custom events/logic rather than just passing from A to B), which is why I’ve made the checkpoint itself a graphless zone and require the agent to go off-grid.

Is there any recommended/nice way to handle such off-grid situations, rather than just waiting a frame and turning the AI on/off?


#12

Hi

For moving the agent, the ai.Teleport function can be used. See https://arongranberg.com/astar/docs/iastarai.html#Teleport

Also, instead of OnDestinationReached, I would recommend using ai.reachedDestination which handles many special cases in a lot nicer ways.