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

How to add new value to array

Discussion in 'Scripting' started by Deleted User, Jan 12, 2018.

Thread Status:
Not open for further replies.
  1. Deleted User

    Deleted User

    Guest

    Hello all!

    For example I have array:
    Code (CSharp):
    1. public static int[] Level1Stars;
    I would like to create different int value from another script and add this int value to this array.
    For example:

    Code (CSharp):
    1. int a = 1;
    2. int b = 2;
    3. int c = 3;
    And if I create new int i would like to add it to my existing array. How can I correct write this code?
     
  2. ihgyug

    ihgyug

    Joined:
    Aug 5, 2017
    Posts:
    194
    To declare and initialize an array you can do so :

    Code (csharp):
    1.  public int [] level1Stars = {1, 2, 9, 4, 6, 7, 9,}
    level1Stars [0] would be equal to 1 (arrays start from 0), level1Stars[1] would be equal to 2 etc...and you can change them like this :
    Code (csharp):
    1.  level1Starts [1] = 9 //changing from 2 to 9
    Or you can declare and initialize them like this :
    Code (csharp):
    1.  public int [] level1Stars =  new int [5] //the elements in your array
    2. level1Stars [2] = 5 //changing the third element of the array
    Another way is to simply declare the array without specify the size, then you can change the size in the inspector from unity and drag stuff in there, like gameobjects or values depending on the array type.

    Code (csharp):
    1.  public int [] level1Stars;
     
    Last edited: Jan 12, 2018
  3. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    You can use array resize but if you are going to be adding to it during runtime you are probably better off just using a list instead.
     
  4. boxhallowed

    boxhallowed

    Joined:
    Mar 31, 2015
    Posts:
    513
    You really should be using list.
     
  5. Deleted User

    Deleted User

    Guest

    Thank you guys for your reply.

    I know some thing about arrays and I made it from another way:
    Code (CSharp):
    1. public static int[,] StarsInLevel = new int[3,20];
    So, now I just need to use indexes. I know my question is dumb :D

    Now I have found a solution to my problems. But, I asked this because I was wondering if I could just create a new value that could simply be added to the array without first declaring the array boundaries. Ie if I add the value and the size of the array will automatically increase by 1.


    For example:
    Code (CSharp):
    1. int[] value;
    So, now array size for example is 0.
    Then I add to this array some new :
    Code (CSharp):
    1. int somevalue = 123;
    And now size of array value will automatically be 1.

    I didn't know is it possible to add value and if it is then how.
     
  6. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,186
    Array's don't adjust. Once set, you have to use the Resize to resize them. You can't just add to it if it goes beyond the boundaries.

    List, dictionaries, and a few other collections allow adding and removing.

    Both of these were covered by other post.
     
  7. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Just use a list, it saves you having to resize arrays;

    Code (CSharp):
    1.     private List<int> _myInts = new List<int>();
    2.  
    3.     public void AddToList(int value)
    4.     {
    5.         _myInts.Add(value);
    6.     }
     
  8. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    if you don't know what the size will be when you define the collection, you should really just use a List, that way you can just add to it at runtime and it will all just work.
     
  9. Deleted User

    Deleted User

    Guest

    Thanks to all! Problem solved! :)
     
  10. Deleted User

    Deleted User

    Guest

    Guys, I have new question.

    For example if I use:
    Code (CSharp):
    1. public GameObject[] objects;
    I can see this array in the inspector and I can add to it GameObjects.

    But if I use:
    Code (CSharp):
    1. public GameObject[,] objects;
    I cant see this array in the inspector. So, my question is, how to see multidimensional arrays in the inspector? Or how can I put GameObjects in it? I dont want use GameObject.Find to put objects in array.
     
  11. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,186
    You would need to make a custom inspector to access multidimensional arrays. Not sure how that would be done as my editor scripting skills is something that I am working on.
     
  12. Deleted User

    Deleted User

    Guest

    And one more question, if I have array:
    Code (CSharp):
    1. public GameObject[] obj = new GameObject[20];
    How can I get index of array to set it in int variable?
     
  13. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Not sure what that question is asking. Get the index of a GameObject in the array?
    Get the length of the array? How to use an index to set a variable?
     
  14. Deleted User

    Deleted User

    Guest

    No,I know how to get lenght. I mean for example:

    Code (CSharp):
    1. public GameObject[] obj = new GameObject[5];
    2.  
    3. //OR
    4.  
    5. public GameObject[,] obj = new GameObject[3,20];
    So, I would like to convert index of GameObject[3] to int. So this int must be 3.
    Or, maybe if it is possible - GameObject[2,15] to int. So, for example first index 2 - int a = 2; Or second index 15 - int a = 15;

    Sorry, If my english not so clear :)
     
  15. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    An array index is an int. Do you mean you want to find out at which index a certain gameobject is in an array? Maybe you should explain what it is you are trying to achieve as I think maybe you are going about it the wrong way.
     
  16. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ya, it's confusing ... you're saying you know it's '2' but then want to find out it's '2' :) That's what your explanation sounded like to me.
     
  17. Deleted User

    Deleted User

    Guest

    As said WarmedxMints I want to find out at which index a certain gameobject is in an array.
     
  18. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
  19. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
  20. Deleted User

    Deleted User

    Guest

    Thank you! Will try it now).

    I will try to explain what I would like to made:

    For example I have level in which are some three objects. When I take this object I save value from 0 to 3 depending on how much objects I was take in level. I save this value to 2d array[chapterindex,levelindex]. So I can easily find how much objects I had collect in certain chapter and level.

    Now, I have some levels buttons in menu with 3 stars and I would like to "setactive" as many stars as it collected in level. So, it is where I stuck. I would like to make some array of stars of all chapter or maybe make different array for every buttons which will contain 3 objects of stars which I would like to "setactive" depending on progress.

    So, I just thinking how to use my existing array of progress with array which contains stars of buttons.

    My previous testing script was:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class StarsMenuScript : MonoBehaviour
    4. {
    5.     public GameObject[] Chapter1Level1Stars;
    6.  
    7.     //public int[,] starsinlevels;
    8.  
    9.     public void Awake()
    10.     {
    11.         //int[,] starsinlevels = SaveGameScript.StarsInLevel;
    12.  
    13.         /*for(int i = 0; i < 20; i++)
    14.         {
    15.             //Chapter1Buttons[i].
    16.         }*/
    17.  
    18.         SaveGameScript.Load(1,1);
    19.         int Stars = SaveGameScript.StarsInLevel[1, 1];
    20.         print("Stars " + Stars);
    21.  
    22.         for (int i = 0; i < Stars; i++)
    23.         {
    24.              Chapter1Level1Stars[i].SetActive(true);
    25.         }
    26.     }
    27.  
    28. }
    29.  
    But it is using only one array with 3 stars and array with progress.
     
  21. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Hmm. That sounds like you just want to retrieve the value, not the index of it. Maybe I don't understand, sorry.
     
  22. boxhallowed

    boxhallowed

    Joined:
    Mar 31, 2015
    Posts:
    513
    I think there is a language barrier here, but let me see if I can get this right. Essentially you want to "collect" your "stars" and have a progress indicator for the amount collected for that "level". Each "level" has a new different number of "stars" to "collect". Am I close?
     
  23. Deleted User

    Deleted User

    Guest

    Hi, yes, you are right. But I was asking about index of array just for my knowledge.

    Now I found solution. I dont know is it a good practice to made by this way or no. And I have one new question. I had problem, now I solved it, but maybe someone can say me where I am right or where no. So there is some code for saving data in file:

    Code (CSharp):
    1. public static int[,] StarsInLevel = new int[2,20];
    2.  
    3.  
    4.     public static void Save(int chapterIndex, int levelIndex)
    5.     {
    6.         BinaryFormatter bf = new BinaryFormatter();
    7.         FileStream file = File.Create(Application.persistentDataPath + "/Save.dat");
    8.         PlayerProgress data = new PlayerProgress();
    9.  
    10.         data.starsinlevel[chapterIndex,levelIndex] = StarsInLevel[chapterIndex,levelIndex];
    11.  
    12.         bf.Serialize(file, data);
    13.         file.Close();
    14.     }
    15.     public static void SaveAll()
    16.     {
    17.         BinaryFormatter bf = new BinaryFormatter();
    18.         FileStream file = File.Create(Application.persistentDataPath + "/Save.dat");
    19.         PlayerProgress data = new PlayerProgress();
    20.  
    21.         data.starsinlevel = StarsInLevel;
    22.  
    23.         bf.Serialize(file, data);
    24.         file.Close();
    25.     }
    26.  
    27.     public static void Load(int chapterIndex, int levelIndex)
    28.     {
    29.         if (File.Exists(Application.persistentDataPath + "/Save.dat"))
    30.         {
    31.             BinaryFormatter bf = new BinaryFormatter();
    32.             FileStream file = File.Open(Application.persistentDataPath + "/Save.dat", FileMode.Open);
    33.             PlayerProgress data = (PlayerProgress)bf.Deserialize(file);
    34.             file.Close();
    35.  
    36.             StarsInLevel[chapterIndex, levelIndex] = data.starsinlevel[chapterIndex, levelIndex];
    37.         }
    38.         else
    39.         {
    40.             StarsInLevel[chapterIndex,levelIndex] = 0;
    41.         }
    42.     }
    43.     public static void LoadAll()
    44.     {
    45.         if (File.Exists(Application.persistentDataPath + "/Save.dat"))
    46.         {
    47.             BinaryFormatter bf = new BinaryFormatter();
    48.             FileStream file = File.Open(Application.persistentDataPath + "/Save.dat", FileMode.Open);
    49.             PlayerProgress data = (PlayerProgress)bf.Deserialize(file);
    50.             file.Close();
    51.  
    52.             for (int chapter = 0; chapter < 2; chapter++)
    53.             {
    54.                 for (int level = 0; level < 20; level++)
    55.                 {
    56.                     StarsInLevel[chapter, level] = data.starsinlevel[chapter, level];
    57.                     print("Chapter" + chapter + "Level" + level +"="+ StarsInLevel[chapter, level]);
    58.                 }
    59.             }
    60.         }
    61.         else
    62.         {
    63.             for (int chapter = 0; chapter < 2; chapter++)
    64.             {
    65.                 for (int level = 0; level < 20; level++)
    66.                     StarsInLevel[chapter, level] = 0;
    67.             }
    68.         }
    69.     }
    70. }
    71.  
    72. [Serializable]
    73. class PlayerProgress
    74. {
    75.     public int[,] starsinlevel=new int[2,20];
    76. }
    And save:

    Code (CSharp):
    1. private void SaveStarsCollected()
    2.     {
    3.         SaveGameScript.LoadAll();
    4.         SaveGameScript.StarsInLevel[ChapterIndex,LevelIndex] = StarsCollected;
    5.         SaveGameScript.SaveAll();
    6.     }
    So, problem was that before I was used only Save method in first script by index and level - it was saving only one value from array. Problem was that when I save 1 level it all is ok. But when there is save in array for first level and I save second level - it saves second level, but first level value sets to 0. I think it rewrite all array and set only 1 value that I set from SaveScript(when was this problem I dont used "SaveGameScript.LoadAll()"). So I decide to try to add method SaveAll and LoadAll and before Saving I load array and then add to array a new value. So now it works.


    But maybe I'm wrong. Could someone tell me if I'm right? Or are there any nuances when using this type of preservation?

    Once again, I remind You that before I solved the problem there were only two methods: "public static void Save(int chapterIndex, int levelIndex)" & "public static void Load(int chapterIndex, int levelIndex)".
    So, after I add SaveAll and LoadAll and add LoadAll before all actions in Save method - it started to works as I want. Seems like previous way just resaves all array and saves only one value.


    Thanks for all who answers me :)
     
  24. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Yes, you were overwriting the array because you were only saving the latest data at the chapter & level indexes. You could have added those values to the StarsInLevel array before assigning to the data variable :)
    That is pretty much what you did, except that you went the round-about way, with reloading.
     
  25. Deleted User

    Deleted User

    Guest

    This is the first thing that came to my mind. :) It can be so? Or do I need to change something, do you think? Will this code not be very slow?:)
     
  26. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Not the end of the world, but I think if you assign the correct (new) portion to the array and then save it, it makes more sense than reloading and saving (and you get the same thing done). The data should already be there when the player begins. Either they load data, or they have none and then begin earning. You shouldn't need to load it, again, before you save :)
     
  27. Deleted User

    Deleted User

    Guest

    You mean I need to assign saved value to StarsInLevel array from for example Awake() or Start()?
     
  28. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Don't think that's what I meant. I mean, yes you want to load it when the game starts, but that is a separate thing.
    I meant this..
    Code (csharp):
    1. data.starsinlevel[chapterIndex,levelIndex] = StarsInLevel[chapterIndex,levelIndex];
    If you already saved to StarsInLevel while you were playing, then all you need is
    Code (csharp):
    1. data.starsinlevel = StarsInLevel;
    That's a slight modification from what I originally said, when I wasn't paying attention: I thought you were sending the score of the level to the method ;) lol

    Anyways, since the rest of the multi-dimensional array should have info in it from the most recent level + any other previously played or loaded data, that assignment should work. When I said you don't have to reload it before every save, it's because of that.. that it was probably loaded once when the game began, and updated as you played. :)
    Try and see if that works.
     
  29. Deleted User

    Deleted User

    Guest

    If I would like to assign value from start of game to "public static int[,] StarsInLevel = new int[2,20];" will it remain after changing the scene, yes?

    And one more question, I dont attache this SaveScript to GameObject. So how can I run Start or Awake? Or there is static Start/Awake that will run without attaching script to gameobject?
     
  30. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, as a static variable it will stay between changing scenes, yes.

    As for how to run it, you can either put it on a gameobject and add Start and/or Awake, or you could simply call the load method when the game starts, from another GameObject. :)
     
  31. Deleted User

    Deleted User

    Guest

    Hah, yeah, forgot about that I can call Load method from another script in start :D So, now I think all questions is resolved :)

    Thank you for your help!
     
  32. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    No problem. :) Enjoy your game.
     
  33. corpsinheretoo

    corpsinheretoo

    Joined:
    May 13, 2013
    Posts:
    11
    Code (CSharp):
    1.         List<GameObject> myList = myArray.ToList();
    2.         myList.Add(myGameObject);
    3.         myArray= myList.ToArray();
    I imagine this is an expensive method - I use it sparingly.
     
  34. Nevleon06

    Nevleon06

    Joined:
    Jun 6, 2021
    Posts:
    3
    Lists are very slow, use NativeLists if you use it (Unity.Collections)
     
  35. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,321
    Please look at the dates of posts before posting. The post you're referring to was years ago.
     
    ZO5KmUG6R and Kurt-Dekker like this.
Thread Status:
Not open for further replies.