Runtime Scan takes 5 mins, Editor Scan takes 10 secs?

I’m using a script to scan 4 graphs at runtime. It weirdly takes 4-5 mins to load it through the script, compared to about 10-15 seconds using the ‘scan’ button in the editor.

Note: when I press the menu scan while it’s already scanning, it takes 4-5 mins to load too. It only takes 10 secs if I press menu scan before any kind of runtime scanning takes place. I use AstarPath.active.Scan();

It only scans it once through a single invoke function and I’m just flabbergasted at how this could be happening. Please help? Thank you

Anyone? Please help I don’t know what to do next

Hi

What exact code are you using to scan the graph?
Also, do you mean a difference between play mode and edit mode or one between the editor and a standalone player?

I just use
AstarPath.active.Scan();
And I mean the difference between play mode and editor mode, like while I’m working on the game in the Unity editor.
There is just such a marked difference in speed between my runtime scan using that code and when I just press ‘scan’ in the editor (menuscan). I also see it freezing for a while on something like ‘Assigning graph to indices’.

As for the scene, I have about 100 trees with capsule colliders, spread out on 16 tiles (4x4) of 30x30 size. Here are my settings for my graphs (4 of them)

That is very strange. It definitely shouldn’t take more than 10 seconds. In a test scene scanning a similarly sized graph takes about 900 ms (though my scene is probably simpler than yours).

Which version of the package are you using?

And again. Please post the exact code (including context) you are using to scan the graphs. :slight_smile:

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

public class NewGameSettings : MonoBehaviour
{
    public int startType; // 1 - start from new game , 2 start from load game
    public int startScenarioSetting;
    public int mapSize; // 0 - tiny 1 - regular 2 large 3 - huge 4 - gigantic
    public int currentScene;
    public string saveGameNameToLoad;
    public int newAgentsToGenerate;
    public int tilesToGenerate;
    private int levelInitProcessNumber;

    private int percentageCounter;
    private int hintCounter;

    private GameObject ingameLoadingScreen;
    private TMP_Text ingameLoadingText;
    private TMP_Text ingameHintText;
    private int loadingSequenceNum;
    public bool finishedLoading;

    // Start is called before the first frame update
    void Start()
    {
        currentScene = 1;
        DontDestroyOnLoad(gameObject);
    }

    private void Update()
    {
        if(currentScene == 2 && levelInitProcessNumber != 2)
        { // current scene is modified by GC_UI_Controller and Title_UI_Controller
            if(ingameLoadingScreen == null)
            {
                ingameLoadingScreen = GameObject.Find("InGame Loading Screen");
                RandomizeHints();
            }
            if(levelInitProcessNumber == 0 && !IsInvoking("LevelInit"))
            {
                Invoke("LevelInit", 1);

            }
            if(levelInitProcessNumber == 1 && AstarPath.active.IsAnyGraphUpdateInProgress == false)
            {
                Invoke("ActivateAliveAgents", 1);
                levelInitProcessNumber = 2;
                if (startType == 2)
                {
                    Invoke("RemoveLoadingScreen", 1);
                }
            }

        }
        if(AstarPath.active != null)
        {
            
            if (AstarPath.active.IsAnyWorkItemInProgress == true && finishedLoading == false)
            {
                loadingSequenceNum = 1;
                if(ingameLoadingScreen == null)
                {
                    ingameLoadingScreen = GameObject.Find("InGame Loading Screen");
                }
                if (ingameLoadingScreen != null)
                {
                    ingameLoadingText = ingameLoadingScreen.transform.Find("InGame Loading Text (TMP)").GetComponent<TMP_Text>();
                    ingameHintText = ingameLoadingScreen.transform.Find("Loading Screen Hint Text (TMP)").GetComponent<TMP_Text>();
                    ingameLoadingScreen.transform.localScale = new Vector3(1, 1, 1);
                    Time.timeScale = 0.001f;
                }
                percentageCounter += 1;
                hintCounter += 1;
                if(percentageCounter < 11900)
                {
                    ingameLoadingText.text = "Building World, " + percentageCounter / 120 + "%";
                }
                else
                {
                    ingameLoadingText.text = "Building World, 99%";
                }
                if(ingameHintText.text == "")
                {
                    ingameHintText.text = FindObjectOfType<SC_Strings_Catalog>().ar_translatedStrings_Hints[Random.Range(1, 11)];// change max
                }
                if(hintCounter > 3000)
                {
                    RandomizeHints();
                    hintCounter = 0;
                }
            }
            if(loadingSequenceNum == 1 && AstarPath.active.IsAnyWorkItemInProgress == false)
            {
                RemoveLoadingScreen();
            }
        }
    }

    public void RandomizeHints()
    {
        GameObject.Find("InGame Loading Screen").transform.Find("Loading Screen Hint Text (TMP)").GetComponent<TMP_Text>().text = FindObjectOfType<SC_Strings_Catalog>().ar_translatedStrings_Hints[Random.Range(1, 11)]; // change max
        FindObjectOfType<InGameLoadingScreenScript>().RandomizeImage();
    }

    public void RemoveLoadingScreen()
    {
        Time.timeScale = 1;
        ingameLoadingScreen.transform.localScale = new Vector3(0, 0, 0);
        loadingSequenceNum = 2;
        ingameLoadingScreen.GetComponent<Image>().sprite = null;
        FindObjectOfType<CameraDolly>().enableCameraControls = true;
        finishedLoading = true;
        CancelInvoke("RemoveLoadingScreen");
    }

    private void LevelInit()
    {
        levelInitProcessNumber = 1;
    }

    public void GenerateWorld()
    {
        //FindObjectOfType<GC_Terrain_Generator>().mapType = 4;
        FindObjectOfType<GC_Terrain_Generator>().GenerateRandomTerrain();
        FindObjectOfType<GC_WeatherSeasons_Controller>().LoadTerrainIntoVariable();
        FindObjectOfType<GC_Time_Controller>().sun.transform.eulerAngles = new Vector3(80, 150, 0);
        FindObjectOfType<GC_Time_Controller>().month = 1;
        FindObjectOfType<GC_Time_Controller>().day = 1;
        FindObjectOfType<GC_Time_Controller>().year = 102;
        FindObjectOfType<GC_Time_Controller>().hour = 12;
        FindObjectOfType<GC_Time_Controller>().minute = 0;
        //FindObjectOfType<GC_Terrain_Generator>().GenerateTerrain(tilesToGenerate);
        GC_StoryBrain storyBrain = FindObjectOfType<GC_StoryBrain>();
        for (int i = 0; i < storyBrain.ar_storyVariables.Length; i++)
        {
            storyBrain.ar_storyVariables[i] = 100;
        }
        // Harvest modules are generated in generate terrain
        //FindObjectOfType<GC_StoryBrain>().GenerateInitialHumanoids(5);

        //GraphScan();
        //ActivateAliveAgents();
        //AstarPath.active.Scan();
        //var graphToScan = AstarPath.active.data.gridGraph;
        //AstarPath.active.Scan(graphToScan);
        //graphScanStep += 1;
        Invoke("GenerateScenario", 1);
    }
    public void GenerateScenario()
    {

        for (int i = 0; i < Random.Range(2, 6); i++)
        {
            FindObjectOfType<GC_StoryBrain>().GenerateCreatureHerd();
        }
        FindObjectOfType<GC_StoryBrain>().GenerateStartScenario(startScenarioSetting);
        FindObjectOfType<GC_Terrain_Generator>().GenerateHarvestablesNewMap();
        //AstarPath.active.data.DeserializeGraphs();
        //FindObjectOfType<GenBoundsGraphUpdater>().RefreshGraphs();
        //AstarPathEditor.MenuScan();
        AstarPath.active.Scan();
    }

    

    public void LoadAGameOnStart()
    {
        Debug.Log("Starting as type 2");
        FindObjectOfType<GameSerializer>().LoadEvent(saveGameNameToLoad);
        AstarPath.active.Scan();
        ActivateAliveAgents();
    }

    public void ActivateAliveAgents()
    {
        foreach (AI_Agent_Brain aiBrain in FindObjectsOfType<AI_Agent_Brain>())
        {
            if (aiBrain.consciousnessMode != 4 && aiBrain.enabled == false)
            {
                aiBrain.enabled = true;
                aiBrain.ActivateAgent();
            }
        }
    }
}

Have you checked the Unity profiler?
And have you verified that it is the Scan call that takes all that time, and that it is only called once?

Above is the exact code I’ve been trying to use. This script is in my title scene, it doesn’t get destroyed upon scene change and it controls things like the loading screen, and triggering terrain and map object generation upon loading the game scene.
One thing I did notice is that, once Astarpath.active.scan() is already working, if I press the menu scan it also takes a long time to load (about 1 minute per graph x 4)

Let me check right now. And thank you so much for taking the time looking at this, I’m going insane cause I remember it loading a lot faster before I started using multiple, smaller terrains instead of just one big one

I also can’t really see how LoadAGameOnStart or GenerateScenario get called. Must be from another script.

Yes it gets called from another script. Here is a screenshot of the profiler while it’s scanning: :

Hi

That’s not from a scan. That’s from something else. The scan should all happen during a single frame. You can expand the profiler to reveal more info.

1 Like

Stripped down all my code and found what was going on, anyway thank you for taking the time to help, I’ll review your asset on the store :+1:

1 Like