Currently, I am working on an RTS that involves units and buildings as is standard. The units navigate around the buildings just fine; however, when told to move TO a building (using AI move to & having buildings as obstacles (high-cost pathing areas)) the units approach the building but then typically move to a particular side or corner of the building. This is due to the pathfinding agent wanting to avoid as much of the high-cost region under and just around the building as possible and “hair-splitting” about which side has slightly less high cost in the path. This results in melee and resource-gathering units taking longer to reach buildings as they path to non-optimal sides of the building.
I want units to move directly to buildings. I have a few ideas but have no idea how to implement them.
Waive extra cost of high-cost region if it is sufficiently small.
Ignore the high-cost region under and just around the specific building the unit is pathing to.
Edit the created path to get close enough to the building, then do a more crude movement method to get the unit through the high-cost area to collide with the building.
I have no idea how to do any of the following and am open to other ideas as this problem has certainly been solved before.
I would suggest you ignore the target building’s effect on pathing altogether and let the unit do their action when they collide. (point 2 in your list)
For the next part I am not 100% sure but hear me out…
What if you don’t ever consider any building for your pathfinding? Your units will collide with them and slide past them. (as long as they are convex and the unit can pass between them)
Think about what behavior would you want if the enemy has blocked their base entrance with buildings and you issue an attack inside the base.
Would you want your units to go to the other end of the map because there is a second entrance there?
Would you want them to ignore your order because they can’t find a path?
Or would you rather have them bunch up at the entrance against the blockade.
I like the second option as well; however, I do not know how I would go about implementing that.
As for the movement questions: The maps will be laid out such that detours will not be quite as extreme as to go to the other side of the map. Despite this, detours will exist and will be significant. In this case, should the player not want such detours to occur, they should issue an attack command outside of but in sight range of the choke point in question, then issue a queued attack command to the base inside the choke point. This will cause the units to move outside of the desired choke point, find the player-built buildings in range, attack them, and then move into the base. I do not want units to ignore commands because of player-built obstacles. This is why I have buildings set to high-cost path areas. They will go around if possible, but if not, they will move along the shortest path ignoring the buildings. They will then see the buildings and attack them, should they be non-allied. In this way, they will only bunch up at the entrance if the blockade is friendly, in this case, it was the player or their ally who made such a blockade and will need to destroy it to move out.
I really don’t have any idea how to ignore a specific obstacle on the navmesh.
About the units being stuck - you can probably slide the units along the surface. I expect truly perpendicular paths to slide to either side because of floating point rounding error but I’ve not tried it. If you say that it is worse, you are probably right.
i use an interface for this that returns a move location.
on the actor (building) implement the interface
you can add scene points to common locations like a building entrance to the actor
the actor then asks for a movelocation, if it doesn’t implement the interface return the actor location or cursor location
when asking for movelocation you can add a Key lets say an Enum for now which describes what location you want (entrance, closest, furthest etc) also pass through the actor location.
now in the interface you can return a specific scene location, closest scene location or do some math to find an edge.
find direction from building to actor, multiply it by the building bounds and add it to the building location and you have a rough edge.
make sure all of these points are on the NavMesh and it should work fine
I apologize, it’s been a while. I was busy reorganizing my interfaces and bug fixing and didn’t want to jump in too soon if the solution didn’t work. The marked solution was greatly beneficial. It gave me the idea to give the unit an adjusted point within the building to move to, making a direct approach the “cheapest”, even with the extra cost under the building not being perfect. Since buildings don’t have an entrance or point of interest (SC2-sized buildings), I was able to simply calculate the coordinate. Here is my implementation.
After the initial movement command, I run a test to determine if the thing pathed to is a building (they don’t move.) After that, I look through all path points until I find one that is a certain distance from the target or the first one in the array (where the unit is). I then path the unit to move to a calculated point that is still within the building (I don’t move the point far enough to leave any building) but is heavily on the side it approaches. The new path finds the path through the high cost easily, as the shortest one just so happens to be the direct one.