0

This code worked fine and everything but it seemed to pause once the trees were staring to get into their 1000's of instances. The navmesh agent would just wait at it's current position and do nothing until a new batch of trees would placed in and then just move to one and pause again. But once I had it terminate the for loop it would continuously move from tree to tree as desired. Why is this? I thought it updated the frame once the OnCollision code was resolved. Is it because there were too many things in the list for it to sort?

Code:

    void OnCollisionEnter(Collision collision)
{
    GameObject data = GameObject.Find("Data");
    List<GameObject> treeLists = data.GetComponent<DataStorage>().treeList;
    for (removeArea = 0; treeLists.Count > removeArea; removeArea++)
    {
        if (treeLists[removeArea] != null)
            if (collision.gameObject.name == treeLists[removeArea].name)
             {
                 GameObject.Destroy(collision.gameObject);
                 treeLists[removeArea] = null;
                 removeArea = treeLists.Count; //Added this 
             }
    }
}

removeArea was supposed to be for something else which I decided to scrap. It isn't used anywhere else in the code.

Is there any way to make it process the for loop before rendering the next frame?

  • 1
    You're curious why not processing 1000s of entries in a for loop makes other code faster? Might it have something to do with the *thousands of iterations of the loop?* – Draco18s no longer trusts SE Apr 29 '18 at 01:04
  • @Draco18s Wouldn't it just slow down my computer but still work? – Oladam Une Apr 29 '18 at 12:45
  • That's not how loops work. NOTHING else can be processed while the loop is active. Unity will seem to freeze until that loop is done. Now, the rest of your system might not freeze because the OS can kick stuff off the processor, but your game will outright lock up, which matches your description. – Draco18s no longer trusts SE Apr 29 '18 at 17:04

1 Answers1

0

If you have a lot of work to be done that can't all fit into a single update, use a coroutine. But in your case, you may only need to improve your algorithm.

Since you only provided OnCollisionEnter, I can only help improve this method and you will be responsible for modifying the rest of your code to test this.

First change treeList's type from a List to a HashSet in DataStorage. Sets are great when you want fast insert, delete, and contains. More information on sets. With that, you will no longer need to loop through the whole collection to find who collided. Removing the loop also allows you to remove the GameObject right from the set too. This is necessary since you can't have duplicates in a set (where you originally set the gameObject reference to null). Your new OnCollisionEnter is now:

void OnCollisionEnter(Collision collision) {
    GameObject data = GameObject.Find("Data");
    var treeList = data.GetComponent<DataStorage>().treeList;

    // compare references
    if (treeList.Contains(collision.gameObject)) {
        treeList.Remove(collision.gameObject);
        GameObject.Destroy(collision.gameObject);
    }
}

I hope this helps and starts you on the right path.

Sean
  • 398
  • 2
  • 13