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

Copying one Array to another

Discussion in 'Scripting' started by LazySamurai, Sep 21, 2016.

  1. LazySamurai

    LazySamurai

    Joined:
    Mar 12, 2015
    Posts:
    5
    I have an array but I need to transfer that array to another script on a different game object, my first script imports all the sprites I need.

    Code (CSharp):
    1. public class GameLoad : MonoBehaviour {
    2.     public Sprite[] weapons,castle,badg,goodg;
    3.     // Use this for initialization
    4.     void Start () {
    5.         weapons = Resources.LoadAll<Sprite>("Art/Weapons");
    6.         castle = Resources.LoadAll<Sprite>("Art/Castle");
    7.         badg = Resources.LoadAll<Sprite>("Art/Bad Guys");
    8.         goodg = Resources.LoadAll<Sprite>("Art/Good Guys");
    9.  
    10.     }
    and my attempt to bring my sprites into another array on my second script.

    Code (CSharp):
    1. art = GameObject.Find("World");
    2.         GameLoad Art = art.GetComponent<GameLoad>();
    3.         for (int i = 0; i < Art.weapons.Length; i++)
    4.         {
    5.             weapons[i] = Art.weapons[i];
    6.         }
     
  2. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    So long as both arrays are of the same type and size, you shouldn't run into any problems with the for loop you have. You could also just do
    Code (csharp):
    1. weapons = Art.weapons
    Again, so long as they are of the same type.
     
    Mehrdad995 likes this.
  3. LazySamurai

    LazySamurai

    Joined:
    Mar 12, 2015
    Posts:
    5
    exactly the same, mind you that both scripts are on a different object would that make a difference?
    Code (CSharp):
    1. public class EnemyStats : MonoBehaviour {
    2.     public Sprite[] weapons, enemies;
    3.     public GameObject art;
    that's the second script, both public sprite arrays
     
  4. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    There may be some confusion, but you've posted some code that looks to me like it works 100%.
    @Vedrit pointed out a slightly more effecient way to do it.

    Did you have an actual question or problem. You don't seem to actual state that any errors or problems occurred or what those errors might have been. The original post looks like it should work 100%
     
  5. Boz0r

    Boz0r

    Joined:
    Feb 27, 2014
    Posts:
    419
    Did you try googling for array copy? C# has an Array.Copy method in its standard library.

    A question I have, though, is why do you need to copy it?
     
  6. LazySamurai

    LazySamurai

    Joined:
    Mar 12, 2015
    Posts:
    5
    Well the sprites from my first array don't go to the second, my second array just stays empty. The reason I want to copy it is for learning purposes and I think it would be a lot easier on the eyes in the code. The first time trying it I tried @Vedrit code, and still didn't work that's why I went to the for loop, my next attempt will be Array.Copy.
     
  7. LazySamurai

    LazySamurai

    Joined:
    Mar 12, 2015
    Posts:
    5
    Problem solved, I don't want to talk about it... stupid me didn't have it under "Update" had it under "Start" thanks all! Much appreciated!
     
  8. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    That's not necessarily a problem. The only reason I think this would have solved the problem was because the sprites hadn't been loaded into the first arrays when the other script tried to grab them.
    If that is the case, a cheaper solution might be
    Code (csharp):
    1.  
    2. public class GameLoad : MonoBehaviour {
    3.    public Sprite[] weapons,castle,badg,goodg;
    4.    public enemyStats enemies;
    5.    // Use this for initialization
    6.    void Start () {
    7.         weapons = Resources.LoadAll<Sprite>("Art/Weapons");
    8.         castle = Resources.LoadAll<Sprite>("Art/Castle");
    9.         badg = Resources.LoadAll<Sprite>("Art/Bad Guys");
    10.         goodg = Resources.LoadAll<Sprite>("Art/Good Guys");
    11.         enemies.weapons = weapons;
    12.    }
    13. }
    and
    Code (csharp):
    1. public class EnemyStats : MonoBehaviour {
    2.    public Sprite[] weapons, enemies;
    3.    public GameObject art;
    4.    public void Start(){
    5.       art = GameObject.Find("World");
    6.       art.GetComponent<GameLoad>().enemies = gameObject.GetComponent<EnemyStats>();
    7.    }
    8. }
     
  9. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Its probably what @Vedrit said and your copy was working correctly, but the first script hadn't loaded the sprites yet. So your copy was copying empty arrays. One important thing to understand in unity is the difference between Awake() and Start().

    When your scene is loaded all the GameObjects will have their Awake calls invoked. The order is not guaranteed, but it is guaranteed that every Awake call will happen before any Start call is made. This is where your scripts should be initializing variables internal to the script. Thus your original GameLoad script should be loading all those sprites in Awake.

    Then Unity will call all the Start functions. There is no guarantee which start is called in what order, but you are guaranteed that every Awake function has already been called, and every Start function will be called before any Update is called. This is where you should have scripts call other scripts for their variables. (Since if you initialized them all in Awake you know they are ready).

    So just change your original code in GameLoad from Start to Awake and you should find it working. Also I wouldn't call that copy code in Update.. since that would happen every frame and you really don't want to be copying all those arrays every frame needlessly.
     
  10. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    @takatok suggestion is also a valid one, and might work better than mine.
     
  11. SmartisticGames

    SmartisticGames

    Joined:
    Jun 8, 2014
    Posts:
    8
    First of all I highly recommend to use private attributes in your scripts and create public methods to access to them (encapsulation principle). There I show you an example:

    Code (CSharp):
    1. public class GameLoad : MonoBehaviour {
    2.     private Sprite[] weapons, castle, badg, goodg;
    3.     // Use this for initialization
    4.     void Start () {
    5.         weapons = Resources.LoadAll<Sprite>("Art/Weapons");
    6.         castle = Resources.LoadAll<Sprite>("Art/Castle");
    7.         badg = Resources.LoadAll<Sprite>("Art/Bad Guys");
    8.         goodg = Resources.LoadAll<Sprite>("Art/Good Guys");
    9.     }
    10.      public Sprite[] getWeapons () { return weapons; }
    11.      public Sprite[] getCastle () { return castle; }
    12.      public Sprite[] getBadg () { return bagd; }
    13.      public Sprite[] getGoodg () { return goodg; }
    14. }
    15.  
    Now you can use these methods from all other scripts to get these Sprites and also your project will be more modular.

    On the other hand, if you will use only one instance of GameLoad in your game I also recommend you to make that attributes and methods static, so all instances (in this case one) will share these attributes:

    Code (CSharp):
    1. public class GameLoad : MonoBehaviour {
    2.     private static Sprite[] weapons, castle, badg, goodg;
    3.     // Use this for initialization
    4.     void Start () {
    5.         weapons = Resources.LoadAll<Sprite>("Art/Weapons");
    6.         castle = Resources.LoadAll<Sprite>("Art/Castle");
    7.         badg = Resources.LoadAll<Sprite>("Art/Bad Guys");
    8.         goodg = Resources.LoadAll<Sprite>("Art/Good Guys");
    9.     }
    10.      public static Sprite[] getWeapons () { return weapons; }
    11.      public static Sprite[] getCastle () { return castle; }
    12.      public static Sprite[] getBadg () { return bagd; }
    13.      public static Sprite[] getGoodg () { return goodg; }
    14. }
    15.  
    This allows you to use this methods without any instance :

    Code (CSharp):
    1. public class OtherClass : MonoBehaviour {
    2.     private static Sprite[] weapons;
    3.     // Use this for initialization
    4.     void Start () {
    5.         weapons = GameLoad.getWeapons();
    6.     }
    7. }
    8.  
     
  12. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    It's also worth considering copying by reference versus copying by value. Depending on what you do with the array later this can be significant.
     
  13. LazySamurai

    LazySamurai

    Joined:
    Mar 12, 2015
    Posts:
    5
    Thanks all much appreciated for the advice and your time! :)