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

class array to be accessed by other script

Discussion in 'Scripting' started by aceace012, Sep 25, 2016.

  1. aceace012

    aceace012

    Joined:
    May 29, 2016
    Posts:
    33
    Thank you in advance guys, I am working on a class array to store data of my characters will have to be accessed by other scripts and scenes, therefore I have the below codes. But it happens that the class can not even be accessed by the same script... If I don't use the array but assign the class one by one, this works perfectly, so I know for sure it is declaring and assigning the class problem.

    Please offer your generous help. Thanks a million times!


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class mageScript : MonoBehaviour {
    5.     public static mageScript mageControlManager;
    6.  
    7.     public class mageClass
    8.     {
    9.         public string mageName;
    10.         public int mageLv;
    11.     }
    12.  
    13.     public mageClass[] mages = new mageClass[10];
    14.  
    15.     // Use this for initialization
    16.     void Awake()
    17.     {
    18.         if (mageControlManager == null)
    19.         {
    20.             DontDestroyOnLoad(gameObject);
    21.             mageControlManager = this;
    22.         }
    23.         else if (mageControlManager != this)
    24.         {
    25.             Destroy(gameObject);
    26.         }
    27.     }
    28.  
    29.     void Start () {
    30.         mages[0].mageName = "GukMon";
    31.         mages[0].mageLv = 1;
    32.         print(mages[0].mageLv);
    33.     }
    34.  
    35.  
    36. }
    37.  
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,139
    Why did you choose to nest the mageClass into your mageScript?

    I'm not sure I understand your issue. You're trying to access your mages from another script?
     
  3. aceace012

    aceace012

    Joined:
    May 29, 2016
    Posts:
    33
    yes, that's what I want to do...
     
  4. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    You should give the GameObject this script is on a Tag. Say "MageControlManager"
    Then every other script that needs to access this script should have this in the Start Function:
    Code (CSharp):
    1. GameObject mageController;
    2. mageScript mageScript;
    3.  
    4. void Start()
    5. {
    6.       mageController = GameObject.FindObjectWithTag("MageControlManager");
    7.        mageScript = mageController.GetComponent<mageScript>();
    8. }
    9.  
    10. // then your code can access your mages like this:
    11. mageScript.mages[0]
    Also in general Methods and Classes use the PascalCase (all UpperCase for name beginnings) while variables use the camelCase (first letter is lowercase).

    If you want others to better understand your code at a glance, I'd suggest changing the class names of mageScript and mageClass to MageScript and MageClass
     
    aceace012 likes this.
  5. aceace012

    aceace012

    Joined:
    May 29, 2016
    Posts:
    33
    Thanks mate, I tried but is still show the same error code...
    NullReferenceException: Object reference not set to an instance of an object
    mageScript.Start () (at Assets/Scripts/fac/mageScript.cs:32)
    And also thanks for the advise on naming, I am not a programmer...so that's really great for your advice.
    First Script
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class mageScript : MonoBehaviour
    5. {
    6.     public static mageScript mageControlManager;
    7.  
    8.     public class mageClass
    9.     {
    10.         public string mageName;
    11.         public int mageLv;
    12.     }
    13.  
    14.     public mageClass[] mages = new mageClass[10];
    15.  
    16.     // Use this for initialization
    17.     void Awake()
    18.     {
    19.         if (mageControlManager == null)
    20.         {
    21.             DontDestroyOnLoad(gameObject);
    22.             mageControlManager = this;
    23.         }
    24.         else if (mageControlManager != this)
    25.         {
    26.             Destroy(gameObject);
    27.         }
    28.     }
    29.  
    30.     void Start()
    31.     {
    32.         mages[0].mageName = "GukMon";
    33.         mages[0].mageLv = 1;
    34.         print(mages[0].mageLv);
    35.     }
    36.  
    37.  
    38. }
    39.  
    40.  
    second code
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class testcontrol : MonoBehaviour {
    5.     GameObject mageController;
    6.     mageScript mageScript;
    7.  
    8.     void Start()
    9.     {
    10.         mageController = GameObject.FindGameObjectWithTag("MageControlManager");
    11.         mageScript = mageController.GetComponent<mageScript>();
    12.         print(mageScript.mages[0].mageLv);
    13.     }
    14.  
    15.     // then your code can access your mages like this:
    16.  
    17.     // Use this for initialization
    18.  
    19.  
    20.     // Update is called once per frame
    21.     void Update () {
    22.  
    23.     }
    24. }
    25.  
     
  6. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Heh you didn't mention this in your OP
    Though I should have caught the error anyway.

    Your error is because of this, when you type a line like this:
    Code (CSharp):
    1. MageClass mage = new MageClass();
    C# sets aside a big chunk of memory for the entire MageClass, and it also sets a small box of memory that Points to that big chunk (this is your reference). The variable mage is just that little box.

    Now your line of code here:
    Code (CSharp):
    1. public mageClass[] mages = new mageClass[10];
    Is setting up an an array of 10 of these little boxes. But you haven't actually made C# set aside memory for all those Big Mage Class objects. and right now all of those little boxes are pointing to null

    If you add this code to void Awake:
    Code (CSharp):
    1. // this is telling C# to make room in memory for all
    2. // the Mage Objects and making your little boxes
    3. // mage[0], mage[1]  point to those chunks of memory
    4. for (int i=0;i<mages.Length;i++)
    5. {
    6.      mages[i] = new mageClass();
    7. }
    It should fix your error
    Add it after you check for your singleton. There is no point creating all these mage objects if your are just going to destroy them immediately if this isn't the singleton
     
    aceace012 likes this.
  7. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,139
    The reason for your error is you created an empty array that has nothing in it.
    Code (CSharp):
    1.         mages[0] = new mageClass() { mageName = "GukMon", mageLv = 1 };
    2.  
    Also looks like @takatok beat me to it. :)

    I will say if you need an expandable collection, consider switching to list. Unless you know you'll never need more than 10 mages.
     
    aceace012 likes this.
  8. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    And even if you don't switch to lists and stick to an array you should at least code it like this:
    Code (CSharp):
    1. // Now you can set this value in the editor
    2. public int numberOfMages = 10;
    3.  
    4. public mageClass[] mages = new mageClass[numberOfMages];
    5.  
    6. // And in your code whenever you loop through your mages
    7. // Never use the number 10 use mages.Length like this
    8. for (int i=0;i<mages.Length;i++)
    This will also allow you to read that numberOfMages variable from a File, or get it assigned from another class if necessary later.
     
    aceace012 likes this.
  9. aceace012

    aceace012

    Joined:
    May 29, 2016
    Posts:
    33
    YES! This work!!! Thank you so much!!
     
  10. aceace012

    aceace012

    Joined:
    May 29, 2016
    Posts:
    33
    Sure! thanks!
     
  11. aceace012

    aceace012

    Joined:
    May 29, 2016
    Posts:
    33
    sorry..just one more question, maybe I am dumb, but I can't get it done as it show another error..
    A field initializer cannot reference the non-static field, method, or property 'mageDetailScript.numberOfMages'
    Code (CSharp):
    1.   public int numberOfMages = 10;
    2.    public mageClass[] mages = new mageClass[numberOfMages];



    public int numberOfMages = 10;
     
  12. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    Yes. sorry you have to adjust it slightly to this, that was my fault on the original code
    Code (CSharp):
    1. public int numberOfMages = 10;
    2.    public mageClass[] mages;
    3.  
    4. // then in awake at the top of the function
    5. // before you loop through the other code I gave
    6. void Awake()
    7. {
    8.         mages = new MageClass[numberOfMages];
    Its because C# can predetermine the amount of memory to set aside if its a static number. IF you are going to make mages be variable, you have to wait to do it at runtime. Which is the difference.. When its up top its at compile time, when its in the Awake function its at run time
     
    aceace012 likes this.
  13. aceace012

    aceace012

    Joined:
    May 29, 2016
    Posts:
    33
    Thank you, you have helped so much.
    You not only help solve a problem..but also educate me on coding and programming..
    I owe you my greatest thanks.
     
  14. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Why not use List instead?

    Code (CSharp):
    1. var classList = new List<BaseClass>()
    2.  
    3. classList.Add(MageClass);
    4.  
    5. // Then
    6. foreach (var professions in classList)
    7. {
    8.   // Logic
    9. }
    10.  
    11. // In the baseclass you can have monobahvoir as public type so you can add what ever script
    12. // you want.Just make a interface so that methods can be accessed.
    13. public Monobehavoir AnyScriptNamer { get; set; }
    14.  
    15.  
     
    Last edited: Sep 25, 2016
    aceace012 likes this.
  15. takatok

    takatok

    Joined:
    Aug 18, 2016
    Posts:
    1,496
    It was suggested by @Brathnann I was just pointing out better practices if he was going to use an array then just assigning an arbitrary const int
     
    aceace012 and Ironmax like this.