WMSK provides 3 path finding methods that don’t require an hexagonal grid (for hexagonal grid-based pathfinding see next section):
Open world movement
In this mode, any path can be computed between two points on the map. This mode uses an invisible matrix cost of 2048×1024 positions mapped to the world plane. The ability to cross a point is determined by the unit terrain capability and the crossing cost at each position of this matrix.
Using Path Finding feature with Game Objects added to the viewport
When you set the terrain capability of any unit (using terrainCapability property of Game Object Animator component returned after you add the game object with WMSK_MoveTo()) to a value different than ANY, the engine will automatically perform a path search each time you move the unit to a destination position (using again WMSK_MoveTo()).
The path finding engine works by having two precomputed cost matrices: one basic matrix for identifying ground and water positions and another one to store user-defined costs.
The first matrix is automatically computed the first time the engine searches for a path (or when the prewarm option is enabled during the startup of the asset). So, you don’t have to worry about this one. This matrix takes the heightmap and water mask of the scenic style to determine which areas are suitable for water or ground units.
The second matrix allows you to specify custom movement costs on the map. This matrix is accessed through PathFindingCustomRouteMatrix property. Note that each time you use this property a copy of the current matrix is returned. You can use this property to change set the entire cost array at once, for example when player turn changes or when units have different map costs before issuing a MoveTo() call to them.
You would want to specify custom costs because:
-
Some provinces might be blockaded/blocked off by enemy units.
-
Some provinces might have a fortress in the way
-
Some terrain types may be impassable during certain weather conditions on the map
-
Enemy or neutral provinces might be in the way and need to be dealt with
-
Units may need to choose the fastest route, taking into account railway lines and road levels (via attributes in the provinces)
-
A nuke could have been dropped in a province making it off-limits for x number of turns
-
Country X may not have given country Y the right to transport troops through their provinces
-
Diplomatic agreement
-
…
The format of the second matrix (the one returned by PathFindingCustomRouteMatrix) is a linearized 2D array of integers (an int[] in C#). The size of this matrix equals to 2048×1024 positions. On each position of the matrix, the integer value could be:
-
0 (zero): meaning that position is unbreakable.
-
-1: the cost of that position has not yet determined and will be returned on the fly by an event function (see below).
-
1 or more: the custom cost for crossing through this cell.
Check out the different PathFindingCustomRouteMatrixSet functions to fill regions of the matrix with your own values. The demo scene 201 (“Path Finding Advanced”) contains sample code where you can see how to specify the onwership of each country and set this custom route matrix accordingly, so the units can or can’t pass through certain countries.
It’s also possible to set the event OnPathFindingCrossPosition so it will be fired when the path finding engine needs to know the cost for certain location (when the value for the matrix at that position is -1), instead of pre-populating the matrix with PathFindingCustomRouteMatrixSet functions. However, it’s more efficient to use the later set of functions if you need to assign the same cost for a country, a province or a set of regions.
Please refer to the Demo Scenes MapPopulation (demo #503), PathAndLines (demo #504) and PathFindingAdvanced (demo #201) for sample code.
Manually getting paths between two map points (non-grid based)
Simply call map.FindRoute API. This function has several overloads. It can accept two map points and optional movement parameters, like terrain capability, altitude range and max search cost. It returns null if no path is found, or a list of Vector2 values that corresponds to map positions.
There’re several overloads with different parameters, including a non-blocking version called FindRouteAsCoroutine.
For game objects positioned on the viewport, you can just call go.FindRoute(destinationPoint) where go is the gameObject, and it will return the path having into account the unit movement properties, like the terrain capability.
Country to Country path finding
Demo scene 202 in Path Finding Examples folder
WMSK also allows you to determine the optimal connections between 2 countries in the world. The APIs to use are:
FindRoute(startingCountry, destinationCountry) will return the list of country indices between the two countries, including them. You can use country.canCross to determine if the route can pass through any given country. Also country.crossCost allows you to specify a custom cost for crossing that country. And finally each country object has a neighbours array of boundary countries which you may modify to define custom connections between countries.
Province to Province path finding
Demo scene 203 in Path Finding Examples folder
Similar to the previous method but using Provinces. The APIs to use are:
FindRoute(startingProvince, destinationProvince) will return the list of province indices between the two provinces, including them. You can use province.canCross to determine if the route can pass through any given province. Also province.crossCost allows you to specify a custom cost for crossing that province. And finally each province object has a neighbours array of boundary provinces which you may modify to define custom connections between provinces.