Author Topic: Find route advice  (Read 300 times)

Friend123

  • Newbie
  • *
  • Posts: 27
    • View Profile
Find route advice
« on: October 12, 2020, 04:26:20 PM »
Good day!
Need advice on the FindRoute method. I am calculating the path from Russia to the Czech Republic, from capital to capital (red line in the screenshot), but the countries Ukraine and Slovakia belong to my player and the path must go through them as a priority (yellow line in the screenshot). Source code below.
What can be changed to make the algorithm work like the yellow line?
Thanks!

Code
public void MoveUnit(string toCountry) {
Globals.map.pathFindingEnableCustomRouteMatrix = true;
Globals.map.PathFindingCustomRouteMatrixReset();

Globals.map.PathFindingCustomRouteMatrixSet(Globals.map.GetCountry("Ukraine"), -1);
Globals.map.PathFindingCustomRouteMatrixSet(Globals.map.GetCountry("Slovakia"), -1);

Vector2 fromLocation = Functions.link.GetLocation(groupCountryPlaced);
Vector2 toLocation   = Functions.link.GetLocation(toCountry);

float distance = Globals.map.calc.Distance(fromLocation, toLocation) / 1000f / 1000f;
float duration = distance * speedAvg * 2f;

List<Vector2> path = _objectOnMap.FindRoute(toLocation);

if (path != null) {
DrawPathLine(path.ToArray());
_objectOnMap.MoveTo(path, duration, DURATION_TYPE.Route);
}
}

Kronnect

  • Administrator
  • Hero Member
  • *****
  • Posts: 7103
    • View Profile
Re: Find route advice
« Reply #1 on: October 12, 2020, 08:48:10 PM »
Hi,

Use latest beta for WMSK 2 which improves accuracy of pathfinding methods.
In this case, the following code can be used:

 
Code
     void ShowPath() {
            map.pathFindingEnableCustomRouteMatrix = true;
            map.PathFindingCustomRouteMatrixReset();
            map.OnPathFindingCrossPosition += Map_OnPathFindingCrossPosition;

            Vector2 fromLocation = map.GetCountry("Russia").center;
            Vector2 toLocation = map.GetCountry("Czech Republic").center;

            List<Vector2> path = map.FindRoute(fromLocation, toLocation, TERRAIN_CAPABILITY.OnlyGround, maxSearchCost: 1000000, maxSearchSteps: 100000);

            if (path != null) {
                map.AddLine(path.ToArray(), Color.red, 0, 0.5f);
            }
        }

        private float Map_OnPathFindingCrossPosition(Vector2 position) {
            int countryIndex = map.GetCountryIndex(position);
            int ukraine = map.GetCountryIndex("Ukraine");
            int slovakia = map.GetCountryIndex("Slovakia");
            if (countryIndex == ukraine || countryIndex == slovakia) {
                return 1; // basic cost
            } else {
                return 2; // increased cost through other countries
            }
        }

Which renders this:


The Map_OnPathFindingCrossPosition function is called by the path-finding algorithm the first time a position needs to be evaluated and what we return is an increased cost for any country other than Ukraine or Slovakia.

Note 1: for performance reasons you'll want to extract the GetCountryIndex() methods from that event handler so they're not called every time.

Note 2: in this example, the default path finding heuristic formula is DXDY which produces bizarre routes (going North then South). The Euclidean or Manhattan options would be better.



« Last Edit: October 12, 2020, 08:49:46 PM by Kronnect »

Friend123

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Find route advice
« Reply #2 on: October 20, 2020, 07:51:40 AM »
Use latest beta for WMSK 2 which improves accuracy of pathfinding methods.
Good day! I have latest WMSK 1 (bought at 2018)! Do i need to upgrade to version 2? How much it will be cost?

Kronnect

  • Administrator
  • Hero Member
  • *****
  • Posts: 7103
    • View Profile
Re: Find route advice
« Reply #3 on: October 20, 2020, 08:42:10 AM »
The upgrade is $25. Make sure you use the same credentials you used when purchasing the old version:
https://assetstore.unity.com/packages/templates/systems/world-map-strategy-kit-2-150938?aid=1101lGsd

Friend123

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Find route advice
« Reply #4 on: June 03, 2021, 12:54:52 PM »

 
Code
     void ShowPath() {
            map.pathFindingEnableCustomRouteMatrix = true;
            map.PathFindingCustomRouteMatrixReset();
            map.OnPathFindingCrossPosition += Map_OnPathFindingCrossPosition;

            Vector2 fromLocation = map.GetCountry("Russia").center;
            Vector2 toLocation = map.GetCountry("Czech Republic").center;

            List<Vector2> path = map.FindRoute(fromLocation, toLocation, TERRAIN_CAPABILITY.OnlyGround, maxSearchCost: 1000000, maxSearchSteps: 100000);

            if (path != null) {
                map.AddLine(path.ToArray(), Color.red, 0, 0.5f);
            }
        }

        private float Map_OnPathFindingCrossPosition(Vector2 position) {
            int countryIndex = map.GetCountryIndex(position);
            int ukraine = map.GetCountryIndex("Ukraine");
            int slovakia = map.GetCountryIndex("Slovakia");
            if (countryIndex == ukraine || countryIndex == slovakia) {
                return 1; // basic cost
            } else {
                return 2; // increased cost through other countries
            }
        }

Good day.
I continued the pathfinding experiment. This code works fine, but there was a problem with air units. If i change the TERRAIN_CAPABILITY.OnlyGround parameter to TERRAIN_CAPABILITY.Any, then path returns null.
Why is that?

Kronnect

  • Administrator
  • Hero Member
  • *****
  • Posts: 7103
    • View Profile
Re: Find route advice
« Reply #5 on: June 03, 2021, 01:34:48 PM »
Hi,

I tried a similar code in demo scene "001 Standalone" and it works fine:

Code
        void Update() {
            if (Input.GetKeyDown(KeyCode.H)) {

                map.pathFindingEnableCustomRouteMatrix = true;
                map.PathFindingCustomRouteMatrixReset();
                map.OnPathFindingCrossPosition += Map_OnPathFindingCrossPosition;

                Vector2 fromLocation = map.GetCountry("Russia").center;
                Vector2 toLocation = map.GetCountry("Czech Republic").center;

                List<Vector2> path = map.FindRoute(fromLocation, toLocation, TERRAIN_CAPABILITY.Any, maxSearchCost: 1000000, maxSearchSteps: 100000);
                if (path != null) {
                    map.AddLine(path.ToArray(), Color.red, 0, 0.5f);
                } else {
                    Debug.Log("Path is null!");
                }
            }
        }

        private float Map_OnPathFindingCrossPosition(Vector2 position) {
            return 1;
        }

Using OnlyGround or Any work fine, the red path is displayed.

What're you doing in Map_onPathFindingCrossPosition method?

Friend123

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Find route advice
« Reply #6 on: June 03, 2021, 01:53:13 PM »
Using OnlyGround or Any work fine, the red path is displayed.

What're you doing in Map_onPathFindingCrossPosition method?

My simple code:
Code
    float Map_OnPathFindingCrossPosition(Vector2 position) {
        int countryIndex = Globals.map.GetCountryIndex(position);

        if (countryIndex > 0) {
            string countryName = Globals.map.GetCountry(countryIndex).name;

            if (GameController.link.players[ownerID].countriesOwned.Contains(countryName)) {
                return 1; // basic cost
            }
        }

        return 10; // increased cost through other countries
    }

Attached a screenshot of the unit. terrainCapability.Ground is working, terrainCapability.Ani is not

Kronnect

  • Administrator
  • Hero Member
  • *****
  • Posts: 7103
    • View Profile
Re: Find route advice
« Reply #7 on: June 03, 2021, 02:14:24 PM »
Ok, so you have an unity that can't move then you change its terrain capability to Any. That's different from the FindRoute issue, right? Because I tried this code and it works on my end:

Code
List<Vector2> path = map.FindRoute(fromLocation, toLocation, TERRAIN_CAPABILITY.Any, maxSearchCost: 1000000, maxSearchSteps: 100000);

Code
        float Map_OnPathFindingCrossPosition(Vector2 position) {
            int countryIndex = map.GetCountryIndex(position);

            if (countryIndex > 0) {
                string countryName = map.GetCountry(countryIndex).name;

                if (countryName[0] >= 'J') {  // somehow I simulate that I own countries from "A"-"I"
                    return 1; // basic cost
                }
            }

            return 10; // increased cost through other countries
        }

Calling FindRoute works in this case. So there must be something wrong with the unit or GameObjectAnimator parameters.
Before we go into more datail of GameObjectAnimator, can you confirm if the FindRoute call returns path = null for the same code above?

Friend123

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Find route advice
« Reply #8 on: June 03, 2021, 02:44:47 PM »
Ok, so you have an unity that can't move then you change its terrain capability to Any. That's different from the FindRoute issue, right? Because I tried this code and it works on my end:

Code
List<Vector2> path = map.FindRoute(fromLocation, toLocation, TERRAIN_CAPABILITY.Any, maxSearchCost: 1000000, maxSearchSteps: 100000);

Code
        float Map_OnPathFindingCrossPosition(Vector2 position) {
            int countryIndex = map.GetCountryIndex(position);

            if (countryIndex > 0) {
                string countryName = map.GetCountry(countryIndex).name;

                if (countryName[0] >= 'J') {  // somehow I simulate that I own countries from "A"-"I"
                    return 1; // basic cost
                }
            }

            return 10; // increased cost through other countries
        }

Calling FindRoute works in this case. So there must be something wrong with the unit or GameObjectAnimator parameters.
Before we go into more datail of GameObjectAnimator, can you confirm if the FindRoute call returns path = null for the same code above?

Yes, I tried this code: path is null. I will look for the problem in my code. Thanks

Kronnect

  • Administrator
  • Hero Member
  • *****
  • Posts: 7103
    • View Profile
Re: Find route advice
« Reply #9 on: June 03, 2021, 02:48:38 PM »
It should return a path. If you don't find anything suspicious, feel free to send me a pm with a repro. I'll take a look.

Friend123

  • Newbie
  • *
  • Posts: 27
    • View Profile
Re: Find route advice
« Reply #10 on: June 05, 2021, 01:08:01 PM »
It should return a path. If you don't find anything suspicious, feel free to send me a pm with a repro. I'll take a look.
I found the reason!
I had the option "Prewarm at start" enabled. It should be disabled!

Kronnect

  • Administrator
  • Hero Member
  • *****
  • Posts: 7103
    • View Profile
Re: Find route advice
« Reply #11 on: June 05, 2021, 02:25:50 PM »
I've reproduced the issue and it's now fixed in the latest beta so you can keep using Prewarm At Start.
Thanks for reporting this.