Bug? AstarPath.active.Scan not wait RecastGraph process finish

Hi Aron

i don’t know it’s a bug or not.

my game have random dungeon. (2D)

and i use RecastGraph . but the navmesh can not gen completely.

i need open the RecastGraph group in editor , then click the Scan button.

if the RecastGraph group not open still can’t get the correct result.

please check the video for better explanation.

the key code i was use it down below


  public static IEnumerator InitAStartPathFindSync(GameObject _dunRootGo)
{
    //Init AStartSystem
    var go = new GameObject("A*");
    var aStart = go.AddComponent<AstarPath>();
    aStart.logPathResults = PathLog.OnlyErrors;
    aStart.threadCount = ThreadCount.AutomaticHighLoad;
    aStart.scanOnStartup = false;
    aStart.navmeshUpdates.updateInterval = -1; 

    //Generate a mesh for A* to run recast
    DrawNavMesh(_dunRootGo);
    yield return null;

    //add a RecastGraph (r0)
    AddNewRecastGraph(true);

    var r0 = AstarPath.active.data.graphs[0] as RecastGraph;

    r0.SnapForceBoundsToScene();
    
    // rotate to 2D
    r0.rotation = new Vector3(-90f, 0, 0);

    // z <-> y switch
    var size = r0.forcedBoundsSize;
    size.z = size.y;
    size.y = 0;
    r0.forcedBoundsSize = size;

   // same bug with AstarPath.active.Scan()
    foreach (var progress in AstarPath.active.ScanAsync())
    {
        yield return null;
    }

    yield return null;


    // remove the mesh
    // if (mMeshGo != null)
    // {
    //     GameObject.Destroy(mMeshGo);
    // }

    //add RVO
    var simulator = go.AddComponent<RVOSimulator>();
    simulator.workerThreads = ThreadCount.AutomaticHighLoad;
    simulator.movementPlane = MovementPlane.XY;

    yield return null;
}

Hi Aron

i have narrow down the bug with those test code.

using System.Collections.Generic;
using Pathfinding;
using UnityEngine;
using UnityEngine.UI;

public class TestCode : MonoBehaviour
{
    private const float TILE_SIZE = 0.32f;

    public Button step1;
    public Button step2;
    public Button step3;


    private GameObject mMeshGo;

    void Start()
    {
        step1.onClick.AddListener(OnClickStep1Btn);
        step2.onClick.AddListener(OnClickStep2Btn);
        step3.onClick.AddListener(OnClickStep3Btn);
    }


    /// <summary>
    /// Generate a mesh
    /// </summary>
    private void OnClickStep1Btn()
    {
        var dataList = new List<TileRangeInt>()
        {
            new TileRangeInt(2, 2, 6, 10)
        };

        mMeshGo = new GameObject("MeshGo");

        var filter = mMeshGo.AddComponent<MeshFilter>();
        filter.mesh = GenAllTilemapMesh(dataList);

        mMeshGo.AddComponent<MeshRenderer>();
    }

    /// <summary>
    /// Init A*
    /// </summary>
    private void OnClickStep2Btn()
    {
        //Init AStartSystem
        var go = new GameObject("A*");
        var aStart = go.AddComponent<AstarPath>();
        aStart.logPathResults = PathLog.Heavy;
        aStart.threadCount = ThreadCount.AutomaticHighLoad;
        aStart.scanOnStartup = false;
        aStart.navmeshUpdates.updateInterval = 0.1f;


        var rg = AstarPath.active.data.AddGraph(typeof(RecastGraph)) as RecastGraph;
        rg.cellSize = TILE_SIZE * 0.2f;
        rg.useTiles = false;
        rg.minRegionSize = rg.cellSize * 0.25f;
        rg.characterRadius = TILE_SIZE * 0.4f; //Nav的边界
        rg.maxSlope = 0f;
        rg.rasterizeColliders = false;
        rg.rasterizeTerrain = false;
        rg.rasterizeTrees = false;
        rg.rasterizeMeshes = true;
        rg.enableNavmeshCutting = true;


        rg.SnapForceBoundsToScene();
        //旋转到2D
        rg.rotation = new Vector3(-90f, 0, 0);

        //重新对齐Size
        var size = rg.forcedBoundsSize;
        size.z = size.y;
        size.y = 0;
        rg.forcedBoundsSize = size;
    }

    /// <summary>
    /// Scan
    /// </summary>
    private void OnClickStep3Btn() { AstarPath.active.Scan(); }


    public struct TileRangeInt
    {
        public int x;
        public int y;
        public int sizeX;
        public int sizeY;

        public TileRangeInt(int x, int y, int sizeX, int sizeY)
        {
            this.x = x;
            this.y = y;
            this.sizeX = sizeX;
            this.sizeY = sizeY;
        }
    }


    public Mesh GenAllTilemapMesh(List<TileRangeInt> _allNavRangeData)
    {
        var vertices = new List<Vector3>();
        var triangles = new List<int>();
        var normals = new List<Vector3>();

        _allNavRangeData.ForEach(tile =>
        {
            var nowIndex = vertices.Count;
            //V2-----V3
            //|       |
            //|       |
            //V0-----V1
            var V0 = GetPos(tile.x, tile.y);
            var V1 = GetPos(tile.x + tile.sizeX, tile.y);
            var V2 = GetPos(tile.x, tile.y + tile.sizeY);
            var V3 = GetPos(tile.x + tile.sizeX, tile.y + tile.sizeY);

            vertices.AddRange(new[] {V0, V1, V2, V3});

            //0-2-3,0-3-1 顺时针
            triangles.AddRange(new[]
            {
                nowIndex, nowIndex + 2, nowIndex + 3,
                nowIndex, nowIndex + 3, nowIndex + 1
            });

            // var normalDir = Vector3.up;
            var normalDir = Vector3.back;
            normals.AddRange(new[] {normalDir, normalDir, normalDir, normalDir});
        });

        var mResultMesh = new Mesh();
        mResultMesh.vertices = vertices.ToArray();
        mResultMesh.triangles = triangles.ToArray();
        mResultMesh.normals = normals.ToArray();
        return mResultMesh;
    }

    private Vector3 GetPos(int _vX, int _vY)
    {
        //2D
        return new Vector3(_vX * TILE_SIZE, _vY * TILE_SIZE, 0);
    }
}

Evn:

Burst 1.3.9
Entities 0.14.0-preview.19
Jobs 0.5.0-preview.14
Unity 2020.1.12f1c1
A* : 4.3.38

Hi

You are setting your graph’s bounding box size to zero on the y-axis. That will make it impossible for it to scan anything. I think the editor field clamps the value to 0.001 which is why it works after you open the editor.

Ah, that accounts for it!

thanks a lot!

1 Like