Handling doors on a GridGraph with AIPath

I’ve scoured the entire forum but I couldn’t find a conclusive answer to this problem.

I need a character (when walking towards a specific location) to stop in front of a door if it’s in his path, wait for it to open, then continue. If however the door is already open, he should just keep going.

Here’s a picture to demonstrate:

Questions:

  1. Where is the best place in code to make the character stop and open the door if the next Node in his path is the door? How can I make him smoothly stop without splitting this path into multiple paths if the door is closed?
  2. Should I constantly check if the next node is a door or should I pre-calculate if there are any doors in the path?
  3. How can I get the remaining path but such that it is in well rounded Vector3’s? GetRemainingPath returns excess coordinates between nodes, but what I really need is the concrete coordinates at the center of each node (the center of the squares). For example, in the above picture we should stop directly under the door (at the center of that node), wait for the door to open and then continue.

I know there are many ways to do this but because my door opening logic is so integrated with how this asset works in the backend it’s hard for me to find an optimal solution. The solution should look very close to the game RimWorld. Here’s an example of how that looks:

Door opening example GIF

Hi

This seems similar to this topic: How to: Adjust Blocked Path Preferences (GridGraph)? - #7 by aron_granberg

There’s no out of the box solution for it right now. Though, I am considering adding the one discussed in the linked thread to the package. Do you think it would solve your case?

I have examined the problem and here are my thoughts.

The problem Denno was having was much more general, and even though it is a good solution, I feel like it is a bit too complex for my use case, unless I missed something. What I was imagining would more be like inserting breakpoints while following a path, so the agent would do something like this:

  1. Start following a path
  2. Constantly check if the next rounded Vector3 (node) in the path is a door. Example: currently on (0,0,0), next node is (1,0,0). It may be worth noting I use a custom TraversalProvider so the agent already completely avoids doors if he cannot go through them.
  3. If the next node (1,0,0) in the path is a door, check if it is open. If it is indeed open, simply keep going. If it is not open, stop at the node in front of the door (the node we reached before we realized there is a door at the next node) and order it to open. During this process keep checking if it’s open, and when it is, continue.

I know my use case may be a bit more specific but I feel like it should be simple enough to implement following the above steps. I’m just not sure how to get the information I need and in which part of the movement update code I should apply this logic.

If this truly cannot be done with the current features, then adding the solution you mentioned would be a start and I’ll continue from there. However, I’d really appreciate if you could think of a way to solve this with what we’ve got already, given the steps above.

Thanks Aron!

This is still a huge problem for me.

What would make my life 1000x easier if there was a way to have a method similar to GetRemainingBuffer() but if it returned exactly what AIPath.path.path returns, AKA a List of whole nodes in the path, and not chopped up Vector3's of which there can be multiple per one single node in the path.

What AIPath.path.path returns (List<GraphNode>) is perfect except it returns the entire path, not just the remaining one. It would also be really useful to be able to call some method to return an X number of upcoming nodes that I can check if they are doors, instead of returning the entire remaining path which could be hundreds of nodes long.

Is there any way to achieve this, or would you please be able to add it in an update? I think it should be simple to implement and it would be a lifesaver for me and my spaghetti code.

Thank you!

Hi

Currently, there is no great solution for this. In the future I want to have a system that allows the path to be split up (like the breakpoints you mention) so that the agent could traverse to one breakpoint, and then a callback would be fired to allow another script to decide what to do here.

This is not really possible with the current script because the agent doesn’t follow a list of nodes. The list of coordinates it follows may be completely different from the list of nodes in theory (if you use modifiers this is very likely).
What you could do is to make a path request from your character’s position, say every 0.1 seconds, and then check the first few nodes in the returned path.

Another solution is to do something like

var buffer = ...;
ai.GetRemainingPath(buffer);
if (AstarPath.active.GetNearest(buffer[1]).node.Tag = something) {
    // Stop and open the door
}

which admittedly is a bit hacky, but might very well be robust enough.

Hey @aron_granberg ! Checking in a year later to see if maybe you’ve implemented something regarding what you said:

“In the future I want to have a system that allows the path to be split up (like the breakpoints you mention) so that the agent could traverse to one breakpoint, and then a callback would be fired to allow another script to decide what to do here.”

I am coming to the part again where I’m implementing doors and something like this would be really useful.

@aron_granberg I know you’re currently away so it takes longer to respond, but I’d really appreciate it so that I know if I have to make my own solution or if something in A*PP already covers this use case. Thank you!