Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Adding, removing and reading list size

Discussion in 'Scripting' started by OutDoorsScene, Sep 21, 2023.

  1. OutDoorsScene

    OutDoorsScene

    Joined:
    Sep 9, 2022
    Posts:
    140
    As long as you don't directly add or remove part of a list inside its forloop. Can a list be safely used within update without ending up with an ObjectDisposedException? i.e. The list would not remove an item and check all its available items simultaneously. Even when an item could be removed at any time.

    Adds object to list when interacting with jump pad.
    Code (CSharp):
    1.  
    2.  private void OnTriggerStay(Collider other)
    3.     {
    4.         Rigidbody rb = other.GetComponent<Rigidbody>();
    5.      
    6.         if (rb)
    7.         {
    8.  
    9.             foreach (var item in jumpedObjects)
    10.             {
    11.                 if (rb == item.body)
    12.                 {
    13.                    return;
    14.                 }
    15.             }
    16.          
    17.             DefaultTools.CounterGravity(rb, 1);
    18.             rb.AddForce(new Vector3(0, JumpForce, 0), ForceMode.VelocityChange);
    19.             jumpedObjects.Add(new JumpedObjects(rb));
    20.         }
    21.          
    22.     }
    23.  
    Removes object from list over time.
    Code (CSharp):
    1.   private void Update()
    2.     {
    3.        
    4.    
    5.         List<JumpedObjects> objectsToRemove = new List<JumpedObjects>();
    6.         foreach (var item in jumpedObjects)
    7.         {
    8.             item.RemoveDelay -= Time.deltaTime;
    9.             if (item.RemoveDelay <=0)
    10.             {
    11.                 objectsToRemove.Add(item);
    12.             }
    13.         }
    14.         foreach (var item in objectsToRemove)
    15.         {
    16.             jumpedObjects.Remove(item);
    17.         }
    18.  
    19.     }
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,143
    If you use a for loop and loop through a list backwards, you can remove items from a list without an error. The issue with going the other way is that when something is removed, it shifts everything in the list down 1 index. While this would still cause stuff to shift, you wont skip over items because the next item in the iteration will not have changed index position.
     
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,843
    I'm not quite sure what you're asking. Yes, you get a warning when modifying a collection in a
    foreach
    loop (note, a warning, not an error). Doesn't have anything to do with being in an Update loop or not.

    If you need to remove elements from a collection in a loop, run over the collection backwards with a for loop, or just build a second collection of elements to remove and run over that collection, removing each of its elements from the former list.
     
  4. OutDoorsScene

    OutDoorsScene

    Joined:
    Sep 9, 2022
    Posts:
    140
    And that will never cause a ObjectDisposedException?
     
  5. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    ObjectDisposedException
    is not something you will ever encounter in regards to a List. Not sure where you even got that from. Unity is also single-threaded. There is no chance these two scripts will be operating on the same list simultaneously.
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,843
    I mean that error is when you're trying to access an
    IDisposable
    object that's already been disposed (though it depends on the specific implementation). I don't think that error is exactly related to the issue the way you think it is.

    IEnumerator<T>
    implements
    IDisposable
    , so you should perhaps only see an exception when you're trying to use an enumerator that has been disposed. Normally when you modify a collection during an enumeration, you will get a "Collection Was Modified" warning/exception.

    So something else was probably going on.
     
    Last edited: Sep 21, 2023
    PraetorBlue likes this.
  7. OutDoorsScene

    OutDoorsScene

    Joined:
    Sep 9, 2022
    Posts:
    140
    I got it from a script that constantly adds and removes, this was 1-2 years ago. I've stayed away from lists in the past.
     
  8. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,843
    Well like we said the error is not at all directly related to
    List<T>
    . It would've been caused by something else you were doing.

    List<T> is probably the most useful thing in the C# library. You're doing yourself a huge disservice by not using them.
     
    Kurt-Dekker and PraetorBlue like this.