Search Unity

Array Out Of Bounds

Discussion in 'Scripting' started by looytroop, Sep 18, 2017.

  1. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    Hello.

    Now this may sound very simple, I know arrays have a fixed size that you set them to, 10 for example and if you try to access index 10 or later or less than 0 it is out of the bounds of the array. This situation in my code I am not really sure what is going on.

    So I have this declaration...
    public Mesh[] LightUpMeshes = new Mesh[5000];

    then I gather a bunch of Meshes into an array called AllMeshes. I check if the mesh is null, if so, I do nothing, otherwise I add that mesh to the list of LightUpMeshes, and it goes out of bounds. I Debug.Log how many meshes are in the AllMeshes array and it was something like 2340.

    Also, I Debug.Log the size of the array before trying to put it into the array. It goes out of bounds when the size is 0.

    These are the important parts of the code.

    public Mesh[] LightUpMeshes = new Mesh[5000];

    MeshFilter[] allMeshes = (MeshFilter[])FindObjectsOfType(typeof(MeshFilter));

    for (int i = 0; i < allMeshes.Length; ++i)
    {
    Mesh objectMesh = allMeshes.mesh;
    LightUpMeshes.SetValue(objectMesh, LightUpMeshes.Length);
    }


    I have also tried the assignment as LightUpMeshes[LightUpMeshes.Length] = objectMesh

    Any help with this would be great, as I feel very dumb for not knowing why this isn't working as I feel like it should be very simple to see where it is going wrong, but I am not sure.

    Thanks for all those who try to help :) I am greatful.
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    This is only a guess, cause what you showed I'm not sure is enough.

    (basic description)

    But ++i means add 1, then process. so it skips 0.
    i++ means process and then add 1.

    Please also use code tags. https://forum.unity.com/threads/using-code-tags-properly.143875/

    I figured out why you're not using the index, you are, just the forum is converting it to italics, thus the importance of code tags. :)



     
    Last edited: Sep 18, 2017
  3. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    Thank you for the help! I will be sure to use code tags next time, I didn't know those exsisted :p so thank you. As for the code I tried starting i at -1 and that failed. So I then tried starting it at 0 again but instead incremented i afterwards via i++ and the same error still occured.
     
  4. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Generally it helps to know what line your error occurs on.

    LightUpMeshes.SetValue(objectMesh, LightUpMeshes.Length); This line may be the issue. The second value is an index, but you are trying to stuff a mesh into index 5000, which doesn't exist. Your array goes up to 4999. Are you trying to just put the mesh into the last slot each time? (LightUpMeshes.Length -1)?
     
  5. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    I am trying to put it into the first slot, so 0 - 4999. I Debug.Log(LightUpMeshes.Length) and it gives me back 0. I also tried using a variable called size, that started at 0 and would increment after I assign a value to the index at size. This returned in the same error. The error is occuring on the line you specified, the LightUpMeshes.SetValue(objectMesh, LightUpMeshes.Length);
     
  6. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Ok, I understand now. And I think the problem is because the variable is public, it's being overwritten in the inspector. If you look at the script in the inspector, you may have an empty array with no slots allocated to it. Length is returning 0 because it has no length, thus you can't assign a value to the index. (and just the out of bounds error)

    Length would still return 5000 if it had the slots allowing you to put values into them.

    You should be able to assign the size of the array in the inspector if you want to go that route, or initialize your array in Start/Awake in the script instead of when you declare the variable.
     
  7. laxbrookes

    laxbrookes

    Joined:
    Jan 9, 2015
    Posts:
    235
    Have you tried using a list instead? All you have to do is initialise it and push each item to it individually. You shouldn't encounter a bounds error this way.

    Code (csharp):
    1.  
    2. //Remember this import...
    3. using System.Collections.Generic;
    4. //... further on
    5.  
    6. // declare and init the list of meshes
    7. public List<Mesh> lightUpMeshes = new List<Mesh>();
    8.  
    9. // get all MeshFilters
    10. MeshFilter[] allMeshes = (MeshFilter[])FindObjectsOfType(typeof(MeshFilter));
    11.  
    12. // loop through the array and push each mesh to the list
    13. for(int i = 0; i < allMeshes.length; i++){
    14.     lightUpMeshes.add(allMeshes[i].mesh);
    15. }
    16.  
    17.  
     
  8. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Yeah, I prefer list myself, I just didn't know what the OP was doing beyond what was shown to determine if there was a reason an array was chosen.
     
    laxbrookes likes this.
  9. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    Actually this code was orriginally a list, but for performance reasons I would like to use an array instead. As my Update function is very heavy (n^2) and I would like to have an array to minimize the impact on the game as much as possible. It also just bugs me because it should work, I am not sure why it is not, even when I make the array size 1,000,000.
     
  10. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    I explained why it is probably giving you an error. Did you try what I suggested?
     
  11. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    Even if I get rid of the code inside the for loop and just write out

    Code (csharp):
    1.  
    2. LightUpMeshes[0] = allMeshes[0].mesh;
    3.  
    This still fails. I feel as though I am not initializing it properly, but I don't see anything wrong with what I am doing.
     
  12. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Note that pre-increment and post-increment do not make any difference in a loop's head in regards to the index (at least in C/C++ and C#). If compilers do not optimize it in that specific case, pre-increment (++i) is just a little more efficient.
     
    Brathnann likes this.
  13. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    ...Already explained....
     
  14. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    So sorry about that, I just saw it, I must have missed it when there were multiple replies, Unity is freaking out on me right now but I will try this in a second. I think you are probably correct. Thank you so much!
     
  15. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Yeah, already established this wasn't the issue anyways. It appears to be the inspector overwriting the array. But this is still good to know.
     
    Suddoha likes this.
  16. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    In regards to the actual problem...

    I'm not sure what you're trying to do anyway?
    You can just use the array that you get back from the FindObjectsOfType method. Copying the references to a new array does not appear to make alot of sense, unless you really need them in a different array (the array returned by that function does not represent an internally managed array, it's newly allocated during the method's execution).

    Either way, since you already tried to avoid lists for 'performance reasons', I'd stronly recommend using .NET's built-in copy methods for arrays, namely Array.Copy and its overloads. It'll be much faster than a loop, as it uses special instructions in the runtime environment which usually make use of hihgly efficient low-level / native operations.
     
  17. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    You were correct, I made the arrays private and everything worked well. Thank you!
     
  18. looytroop

    looytroop

    Joined:
    Jun 22, 2017
    Posts:
    70
    Thank you for this, I will be sure to check that out, and well I just simplified the problem for this post, really I am purging it of null meshes and also checking what shaders are on the meshes and stuff like that. Thank you!