Search Unity

[C#] array index is out of range

Discussion in 'Scripting' started by _HAL_9000, Jul 4, 2015.

  1. _HAL_9000

    _HAL_9000

    Joined:
    Jun 26, 2015
    Posts:
    48
    Hello everyones !
    I have a problem i declare an array and set it's size but unity tell me "Array index is out of range" when i want to use it (line 17-18-19).
    Does it means that the return of getComponents is null ?

    Code (CSharp):
    1.     void Start () {
    2.         Canvas    Board;
    3.         Button[]    buttons;
    4.         Text[]        Texts;
    5.         Image[]     Tiles;
    6.        
    7.         Board = FindObjectOfType<Canvas>();
    8.         if (Board == null)
    9.             print ("Board == null");
    10.         buttons = new Button[4];
    11.         Texts = new Text[13];
    12.         Tiles = new Image[4];
    13.         buttons = Board.GetComponents<Button>();
    14.         Texts = Board.GetComponents<Text>();
    15.         Tiles = Board.GetComponents<Image>();
    16.         print(buttons.Length);
    17.         buttons[0].transform.Translate(0.0f, -0.1402f, 0.0f);
    18.         Texts[11].transform.Translate(0.0f, 0.1402f, 0.0f);
    19.         Tiles[2].transform.Translate(0.0f, 0.1402f, 0.0f);
    20.     }
     
  2. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    I think its because you do
    Code (CSharp):
    1.    buttons = new Button[4];
    2.    buttons = Board.GetComponents<Button>();
    3.  
    Its like basically saying "ignore what I assigned buttons to before and make it the size of however components you find"

    If you then get only 1 or so components, but are looking in the index of 4 for a component, you will get the error.
     
  3. _HAL_9000

    _HAL_9000

    Joined:
    Jun 26, 2015
    Posts:
    48
    Thanx for the response !
    I have tried my script without the "Buttons = new Button[4]" it didn't work.
    I have tried this too but i got the same error message ...

    Code (CSharp):
    1.     void Start () {
    2.         //string returnServer;
    3.         Canvas    Board;
    4.         print ("zaeaze");
    5.         Button    buttons;
    6.         Text        Texts;
    7.         Image        Tiles;
    8.        
    9.         Board = FindObjectOfType<Canvas>();
    10.         if (Board == null)
    11.             print ("Board == null");
    12. //        buttons = new Button[4];
    13. //        Texts = new Text[13];
    14. //        Tiles = new Image[4];
    15.         buttons = Board.GetComponents<Button>()[0]; /* Here are the changes */
    16.         Texts = Board.GetComponents<Text>()[11];
    17.         Tiles = Board.GetComponents<Image>()[2];
    18. //        print(buttons.Length);
    19.         buttons.transform.Translate(0.0f, -0.1402f, 0.0f);
    20.         Texts.transform.Translate(0.0f, 0.1402f, 0.0f);
    21.         Tiles.transform.Translate(0.0f, 0.1402f, 0.0f);
    22. }
     
  4. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Then it means it doesnt have the amount of components you are assuming it has.

    Do this for testing
    Code (CSharp):
    1.         buttons = Board.GetComponents<Button>();
    2.         Texts = Board.GetComponents<Text>();
    3.         Tiles = Board.GetComponents<Image>();
    4.  
    5.          Debug.Log(buttons.length + " " + Texts.length + " " + Tiles.length);
    6.  
    Make sure you are getting the right amount of components

    Why are you doing button number 0, text number 11 and tile number 2? Im not sure if the getcomponents would alway return things in an expected order like you are assuming, why take the risk?
     
  5. _HAL_9000

    _HAL_9000

    Joined:
    Jun 26, 2015
    Posts:
    48
    it seems like the three array have a size of 0 .
     
  6. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    You have a null check, but you continue to run the code under it anyways. Does it print("Board == null");?

    Do you have multiple canvasses?
     
  7. _HAL_9000

    _HAL_9000

    Joined:
    Jun 26, 2015
    Posts:
    48
    Nope, and i don't understand because i have plenty ui objects in my canvas (4 images/13 texts fields ....) ..
     
  8. _HAL_9000

    _HAL_9000

    Joined:
    Jun 26, 2015
    Posts:
    48
    i have only one canvas
     
  9. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Run this and tell me what it responds.
    Code (CSharp):
    1. void Start () {
    2.         Canvas    Board;
    3.         Button[]    buttons;
    4.         Text[]        Texts;
    5.         Image[]     Tiles;
    6.      
    7.         Board = FindObjectOfType<Canvas>();
    8.         if (Board == null)
    9.         {
    10.             print ("Board == null");
    11.             return;
    12.          }
    13.  
    14.         buttons = Board.GetComponents<Button>();
    15.         Texts = Board.GetComponents<Text>();
    16.         Tiles = Board.GetComponents<Image>();
    17.         print(buttons.Length + " " + Texts.Length + " " + Tiles.Length);
    18.     }
     
    Last edited: Jul 4, 2015
  10. _HAL_9000

    _HAL_9000

    Joined:
    Jun 26, 2015
    Posts:
    48
  11. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Then it is not getting any components, but you say you have lots of em, so it might mean the components you are trying to get are not directly on the Canvas gameobject. Are they child objects?
    (I have not played with canvases so I do not know how things are meant to be)
    Based off of a video I just watched of canvases, It seems elements such as buttons and texts are created as Child gameobjects of panels and such.

    In other words, when you click on your canvas gameobject, do you only see a rect transform component, a canvas component, and maybe a graphic raycaster component?
    If so, then you are doing things wrong in the way you are trying to get your buttons and texts.

    Maybe post your project?
     
    Last edited: Jul 4, 2015
  12. _HAL_9000

    _HAL_9000

    Joined:
    Jun 26, 2015
    Posts:
    48
    debug.PNG
    here's my canvas and his differents fields. I would say that they are childs but i'm not sure what you want to say.
     
  13. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Those are gameobjects that have components of buttons, texts, etc.., not components on the actual canvas.

    You might need to do something like this..
    Code (CSharp):
    1. void Start () {
    2.         Canvas    Board;
    3.         Button[]    buttons;
    4.         Text[]        Texts;
    5.         Image[]     Tiles;
    6.  
    7.         Board = FindObjectOfType<Canvas>();
    8.         if (Board == null)
    9.         {
    10.             print ("Board == null");
    11.             return;
    12.          }
    13.         buttons = Board.GetComponentsInChildren<Button>();
    14.         Texts = Board.GetComponentsInChildren<Text>();
    15.         Tiles = Board.GetComponentsInChildren<Image>();
    16.         print(buttons.Length + " " + Texts.Length + " " + Tiles.Length);
    17.     }
     
    Last edited: Jul 4, 2015
    _HAL_9000 likes this.
  14. _HAL_9000

    _HAL_9000

    Joined:
    Jun 26, 2015
    Posts:
    48
    yes ! it print the right amount of text, image, etc thank you ! :)
     
  15. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Id advise you not to alter your components based on just some index number you think is the correct object. Imagine adding 1 new button in the middle somewhere, now all your codes can break.
    Find a way to know exactly what you need, and then search for it, such as searching for the child gameobject by name first and then get its component.

    For example, since you seem to only be interested in a single object of each type, you can maybe use this.
    Code (CSharp):
    1.     void Start()
    2.     {
    3.         Canvas board;
    4.         Button button = new Button();
    5.         Text text = new Text();
    6.         Image tile = new Image();
    7.  
    8.         Board = FindObjectOfType<Canvas>();
    9.         if (Board == null)
    10.         {
    11.             print ("Board == null");
    12.             return;
    13.          }
    14.  
    15.         foreach(Transform child in Board.GetComponentsInChildren<RectTransform>())
    16.         {
    17.             If(child.name == "DesiredButtonObjectsName") button = child.GetComponent<Button>();
    18.             If(child.name == "DesiredTextObjectsName") text = child.GetComponent<Text>();
    19.             If(child.name == "DesiredTileObjectsName") tile = child.GetComponent<Image>();
    20.         }
    21.     }
    Since it seems like you only care about transforming and not the actual component you are looking for, then maybe you dont even need to find the object with the Button Text or Image, and instead just search by name.
     
    Last edited: Jul 5, 2015
  16. _HAL_9000

    _HAL_9000

    Joined:
    Jun 26, 2015
    Posts:
    48
    Ahah dude i was just trying to solve this issue.
    But monoDevelopp tell me that button / text/ tile is used but not set.
     
  17. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    At the beginning of start change it so its like this.
    Code (CSharp):
    1.         Button button = new Button();
    2.         Text text = new Text();
    3.         Image tile = new Image();
    4.  
    The reason it gives you the error is because if you were using the code I gave above, we are setting the variables inside an if statement, but you are probably using it outside the if statement. This meams that if the if statement failed, then your variables were never set. To fix this, we just do "= new Something();" when creating the variable to give it a default value.
    Then, if the if statement was true, it will override the default with the new values, but if it was false, you still have the default values to use.

    Ill edit my code in the previous post to fix this.
     
    Last edited: Jul 5, 2015