Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Do lists work in Unity?

Discussion in 'Scripting' started by hoesterey, Jul 25, 2011.

  1. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    659
    I did a bunch of searches and found some conflicting information on this. Do lists work in unity?

    I'm having a problem where List.Count causes unity to crash:

    Code (csharp):
    1.  
    2. void Start ()
    3.  
    4.     {
    5.  
    6.         for(int i = 0; i < Parts.Count; i++)
    7.  
    8.         {
    9.  
    10.             AddPart(Parts[i], PartChance[i]);
    11.  
    12.         }
    13.  
    14.     }
    15.  
    What I've found is that List.Count causes unity to crash. If I change that code to be anything other then List.Count the game runs fine.

    Any thoughts?
     
  2. zine92

    zine92

    Joined:
    Nov 13, 2010
    Posts:
    1,347
    Could you post the whole code? From what i read. It should work alright. :D

    Here's an example.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class ListEx : MonoBehaviour
    7. {
    8.     List<string> parts = new List<string>();
    9.     List<int> partChance = new List<int>();
    10.  
    11.     void Start()
    12.     {
    13.         for (int i = 0; i < parts.Count; i++)
    14.         {
    15.  
    16.             AddPart(parts[i], partChance[i]);
    17.  
    18.         }
    19.  
    20.     }
    21.  
    22.     void AddPart(string part, int chance)
    23.     {
    24.  
    25.     }
    26. }
    27.  
    28.  
     
    Last edited: Jul 25, 2011
  3. phil_ivey

    phil_ivey

    Joined:
    Dec 3, 2010
    Posts:
    31
    List working
     
  4. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    @ zine92 Those Lists aren't set to anything :p

    Lists work fine in unity - I've used them a fair bit myself.
     
  5. Metron

    Metron

    Joined:
    Aug 24, 2009
    Posts:
    1,137
    if this is the code, then parts will be null upon start... you should initialize it.
     
  6. zine92

    zine92

    Joined:
    Nov 13, 2010
    Posts:
    1,347

    Yeap i know i tried in Unity. Null ref exception. But just to show that List in Unity is okay. And not crash just null ref exception. :D
     
  7. Krysalgir

    Krysalgir

    Joined:
    Aug 30, 2010
    Posts:
    95
    As said before, you should initialize your lists first :

    List<string> parts = new List<string>();
    List<int> partChance = new List<int>();
     
  8. novashot

    novashot

    Joined:
    Dec 12, 2009
    Posts:
    373
    Lists work great unless you alter the list while doing for each loops on them.... so just dont alter it while using it and no problems.
     
  9. Krysalgir

    Krysalgir

    Joined:
    Aug 30, 2010
    Posts:
    95
    I think that it is impossible to alter a list while parsing it with a 'foreach' (it may raise an exception), but you can alter a list while using a 'for'.
     
  10. Daikaze

    Daikaze

    Joined:
    Jun 15, 2011
    Posts:
    13
    Parts is probably of a different size than PartChance (as in PartChance is probably smaller).
     
  11. Ntero

    Ntero

    Joined:
    Apr 29, 2010
    Posts:
    1,436
    If Unity is crashing, are you putting Parts into a property, and if so is it Self Referential?

    i.e.
    Code (csharp):
    1.  
    2. List<int> parts;
    3. public List<int> Parts
    4. {
    5. get
    6. {
    7. return Parts; // as opposed to parts
    8. }
    9. }
    10.  
    It's an off chance, but it's got me more than once where Intellisense capitalizes my variable and makes the property self reference. That causes Unity to crash out with a Stack Overflow.
     
  12. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    659
    Hi,
    Thanks for all the replies.
    Here is the entire class (worked on it a bit more):
    I don't add anything to the list at run-time. Just in the editor before the game is built. The code works fine if I change LetterParts.Count to 4 (the number of items in my lists)

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. using System.Collections;
    5.  
    6. using System.Collections.Generic;
    7.  
    8.  
    9.  
    10.  
    11.  
    12. //This script requires the InventoryManager component to work
    13.  
    14.  
    15.  
    16. [RequireComponent (typeof (InventoryManager))]
    17.  
    18. public class LetterPartAwarder : MonoBehaviour
    19.  
    20. {
    21.  
    22.     bool _lettersAwarded;
    23.  
    24.    
    25.  
    26.         //Letter Part Game Objects
    27.  
    28.     public List<GameObject> LetterParts = new List<GameObject>();
    29.  
    30.    
    31.  
    32.     //the chance that each letter part will drop
    33.  
    34.     public List<int> PartChance = new List<int>();
    35.  
    36.    
    37.  
    38.     // Use this for initialization
    39.  
    40.     void Start ()
    41.  
    42.     {
    43.  
    44.         _lettersAwarded = false;
    45.  
    46.        
    47.  
    48.         //Lets add all the leter parts to our list and the chance that they will drop.  Total chance should be == 100
    49.  
    50.         if(LetterParts.Count != PartChance.Count)
    51.  
    52.             Debug.LogWarning("LetterParts and PartChance list must be the same length");
    53.  
    54.        
    55.  
    56.         for(int i = 0; i < LetterParts.Count; i++)
    57.  
    58.         {
    59.  
    60.             AddLetterPart(LetterParts[i], PartChance[i]);
    61.  
    62.         }
    63.  
    64.     }
    65.  
    66.    
    67.  
    68.    
    69.  
    70.     // Update is called once per frame
    71.  
    72.     void Update ()
    73.  
    74.     {
    75.  
    76.         //For now lets just award letters at the begining of the game.
    77.  
    78.         if(!_lettersAwarded  Time.fixedTime >= .02)
    79.  
    80.         {
    81.  
    82.             InventoryManager _invManager = ((InventoryManager)transform.GetComponent(typeof(InventoryManager)));
    83.  
    84.             foreach(Transform _t in _invManager.InventoryGridList)
    85.  
    86.             {
    87.  
    88.                 InventoryGrid _ig = ((InventoryGrid)_t.GetComponent(typeof(InventoryGrid)));
    89.  
    90.                 for(int i = 0; i < _ig.GridSlots.Count/2; i++)
    91.  
    92.                 {
    93.  
    94.                      GameObject _letterPart = Instantiate(GetRandomLetterPart()) as GameObject;
    95.  
    96.                      _ig.AddObjectToNextOpen(_letterPart);
    97.  
    98.                 }
    99.  
    100.             }
    101.  
    102.            
    103.  
    104.             _lettersAwarded = true;
    105.  
    106.         }
    107.  
    108.     }
    109.  
    110.    
    111.  
    112.     //we add a letter to the list and also update
    113.  
    114.     private void AddLetterPart(GameObject _part, int _chance)
    115.  
    116.     {
    117.  
    118.         LetterParts.Add(_part);
    119.  
    120.         for(int i = 0; i < _chance; i++)
    121.  
    122.         {
    123.  
    124.             PartChance.Add(LetterParts.Count-1);
    125.  
    126.         }
    127.  
    128.     }
    129.  
    130.    
    131.  
    132.     private GameObject GetRandomLetterPart()
    133.  
    134.     {
    135.  
    136.         //Return a letter part based on the part chance
    137.  
    138.         return LetterParts[PartChance[(int)Random.Range(0,99)]];   
    139.  
    140.     }
    141.  
    142. }
    143.  
    Thanks so much! :)
     
    Last edited: Jul 26, 2011
  13. zine92

    zine92

    Joined:
    Nov 13, 2010
    Posts:
    1,347
    Glad it works. :D
     
  14. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    659
    It doesn't work. Sorry if I was confusing.

    The code works fine if I change "LetterParts.Count" to the number 4 (the number of items in my lists). Thing is I really need to use .Count so the code is scale able. :)
     
  15. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    659
    Never Mind I got it. When I changed over to using the editor to add members to the list I still added members in my code. Doh
    Working code:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. using System.Collections;
    5.  
    6. using System.Collections.Generic;
    7.  
    8.  
    9.  
    10.  
    11.  
    12. //This script requires the InventoryManager component to work
    13.  
    14.  
    15.  
    16. [RequireComponent (typeof (InventoryManager))]
    17.  
    18. public class LetterPartAwarder : MonoBehaviour
    19.  
    20. {
    21.  
    22.     bool _lettersAwarded;
    23.  
    24.    
    25.  
    26.         //Letter Part Game Objects
    27.  
    28.     public List<GameObject> LetterParts = new List<GameObject>();
    29.  
    30.    
    31.  
    32.     //the chance that each letter part will drop
    33.  
    34.     public List<int> PartChance = new List<int>();
    35.  
    36.     private List<int> _partChance = new List<int>();
    37.  
    38.     // Use this for initialization
    39.  
    40.     void Start ()
    41.  
    42.     {
    43.  
    44.         _lettersAwarded = false;
    45.  
    46.        
    47.  
    48.         //Lets add all the leter parts to our list and the chance that they will drop.  Total chance should be == 100
    49.  
    50.         if(LetterParts.Count != PartChance.Count)
    51.  
    52.             Debug.LogWarning("LetterParts and PartChance list must be the same length");
    53.  
    54.        
    55.  
    56.         for(int i = 0; i < 4; i++)
    57.  
    58.         {
    59.  
    60.             AddLetterPart(i, PartChance[i]);
    61.  
    62.         }
    63.  
    64.     }
    65.  
    66.    
    67.  
    68.    
    69.  
    70.     // Update is called once per frame
    71.  
    72.     void Update ()
    73.  
    74.     {
    75.  
    76.         //For now lets just award letters at the begining of the game.
    77.  
    78.         if(!_lettersAwarded  Time.fixedTime >= .02)
    79.  
    80.         {
    81.  
    82.             InventoryManager _invManager = ((InventoryManager)transform.GetComponent(typeof(InventoryManager)));
    83.  
    84.             foreach(Transform _t in _invManager.InventoryGridList)
    85.  
    86.             {
    87.  
    88.                 InventoryGrid _ig = ((InventoryGrid)_t.GetComponent(typeof(InventoryGrid)));
    89.  
    90.                 for(int i = 0; i < _ig.GridSlots.Count/2; i++)
    91.  
    92.                 {
    93.  
    94.                      GameObject _letterPart = Instantiate(GetRandomLetterPart()) as GameObject;
    95.  
    96.                      _ig.AddObjectToNextOpen(_letterPart);
    97.  
    98.                 }
    99.  
    100.             }
    101.  
    102.            
    103.  
    104.             _lettersAwarded = true;
    105.  
    106.         }
    107.  
    108.     }
    109.  
    110.    
    111.  
    112.     //we add a letter to the list and also update
    113.  
    114.     private void AddLetterPart(int _partIndex, int _chance)
    115.  
    116.     {
    117.  
    118.         for(int i = 0; i < _chance; i++)
    119.  
    120.         {
    121.  
    122.             _partChance.Add(_partIndex);
    123.  
    124.         }
    125.  
    126.     }
    127.  
    128.    
    129.  
    130.     private GameObject GetRandomLetterPart()
    131.  
    132.     {
    133.  
    134.         //Return a letter part based on the part chance
    135.  
    136.         return LetterParts[_partChance[(int)Random.Range(0,99)]];  
    137.  
    138.     }
    139.  
    140. }
    141.  
    142.