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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

C# NullReferenceException

Discussion in 'Scripting' started by DrexonPl, Mar 19, 2015.

  1. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
    My error:
    Code (csharp):
    1.  
    2. NullReferenceException: Object reference not set to an instance of an object
    3. Main.Start () (at Assets/Resources/Scripts/Main.cs:15)
    4.  
    Code:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Main : MonoBehaviour {
    6.  
    7.    void Start () {
    8.  
    9.      string path = "Prefabs/Units";  
    10.      Object[] Units = Resources.LoadAll (path);
    11.  
    12.      if(Units.Length > 0){
    13.        for(int i = 0; i < Units.Length; i++){
    14.          GameObject unit = Units[i] as GameObject;
    15.          Texture2D unitIcon = unit.GetComponent<Unit>().MenuIcon;
    16.          Texture2D unitIconRo = unit.GetComponent<Unit>().MenuIconRo;
    17.  
    18.          Menu.UnitIconTextures.Add (unitIcon);
    19.          Menu.UnitIconTexturesRo.Add (unitIconRo);
    20.          Menu.UnitNames.Add (unit.name);
    21.          Menu.UnitPaths.Add (path+"/"+unit.name);
    22.        }
    23.      }
    24.    }
    25. }
    26.  
    Script on model
     
  2. edwin_s

    edwin_s

    Joined:
    Mar 10, 2015
    Posts:
    19
    I don't think you can do
    Code (csharp):
    1. unit.GetComponent<Unit>()
    as the type of the script component is not actually 'Unit' - that's just the name of your script.

    That said, I don't know how to actually get the script component. It's probably not good practice anyway, and you may be better off using a tag, and then using
    Code (csharp):
    1. GameObject.FindWithTag
     
  3. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
    Script:
    Unit:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Unit : MonoBehaviour {
    6.    public Texture2D MenuIcon;
    7.    public Texture2D MenuIconRo;
    8. }
    9.  
     
  4. Deleted User

    Deleted User

    Guest

    Two things may of happened, either unit is null because it's not a GameObject, or it does not have the Unit component in that object, feel free to write better log messages etc but this should hopefully point out what is wrong.

    Code (csharp):
    1.  
    2. for (int i = 0; i < Units.Length; i++)
    3. {
    4.     GameObject unit = Units[i] as GameObject;
    5.     if (unit != null)
    6.     {
    7.         Unit u = unit.GetComponent<Unit>();
    8.         if (u != null)
    9.         {
    10.             Texture2D unitIcon = u.MenuIcon;
    11.             Texture2D unitIconRo = u.MenuIconRo;
    12.  
    13.             Menu.UnitIconTextures.Add(unitIcon);
    14.             Menu.UnitIconTexturesRo.Add(unitIconRo);
    15.             Menu.UnitNames.Add(unit.name);
    16.             Menu.UnitPaths.Add(path + "/" + unit.name);
    17.         }
    18.         else
    19.         {
    20.             Debug.Log("unit GameObject does not have Unit component, name: " + unit.name);
    21.         }
    22.     }
    23.     else
    24.     {
    25.         Debug.Log("unit is null, name: " + Units[i].name);
    26.     }
    27. }
    28.  
     
    Schneider21 likes this.
  5. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
  6. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
    help ?
     
  7. skaarjslayer

    skaarjslayer

    Joined:
    Oct 10, 2013
    Posts:
    108
    In response to ESchrauwen, you can definitely get a component by its name. If a game object has a script called "MyScript" attached to it, you can certainly get it by calling myGameObject.GetComponent<MyScript>()

    DrexonPl, it looks like you're loading every asset from that folder. Is every asset in that folder a prefab? And if so, does every single one have a "Unit" component attached to it?
     
  8. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
    http://screenshooter.net/102183697/gjcfdbg
    where is button ?
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class Menu : MonoBehaviour {
    7.  
    8.    public static List<Texture2D> UnitIconTextures = new List<Texture2D>();
    9.    public static List<Texture2D> UnitIconTexturesRo = new List<Texture2D>();
    10.    public static List<string> UnitNames = new List<string>();
    11.    public static List<string> UnitPaths = new List<string>();
    12.  
    13.    public Texture2D IconContainer;
    14.    
    15.    void OnGUI () {
    16.      GUIStyle Container = new GUIStyle ();
    17.      Container.normal.background = IconContainer;
    18.  
    19.      GUI.Box (new Rect(Screen.width / 2 - 200, Screen.height - 40, 400, 50), "", Container);
    20.  
    21.      int offset = 48;
    22.      int j = 0;
    23.      for(int i = 0; i < UnitNames.Count; i++) {
    24.        GUIStyle Icon = new GUIStyle();
    25.        Icon.normal.background = UnitIconTextures[i];
    26.        Icon.hover.background = UnitIconTexturesRo[i];
    27.      
    28.        if(GUI.Button (new Rect(Screen.width / 2 - 199 + (offset * j), Screen.height - 39, 46, 39), "", Icon)) {
    29.          Debug.Log(UnitNames[i]);
    30.        }
    31.  
    32.        j++;
    33.      }
    34.    }
    35. }
    36.  
     
  9. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
  10. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
  11. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Main : MonoBehaviour {
    6.  
    7.    void Start () {
    8.  
    9.      string path = "Prefabs/Units";  
    10.      Object[] Units = Resources.LoadAll (path);
    11.  
    12.      if(Units.Length > 0){
    13.        for (int i = 0; i < Units.Length; i++)
    14.        {
    15.          GameObject unit = Units[i] as GameObject;
    16.          Unit u = unit.GetComponent<Unit>();
    17.          
    18.          Texture2D unitIcon = u.PMenuIcon;
    19.          Texture2D unitIconRo = u.PMenuIconRo;
    20.  
    21.          Menu.UnitNames.Add (u.name);
    22.          Menu.UnitIconTextures.Add (unitIcon);
    23.          Menu.UnitIconTexturesRo.Add (unitIconRo);
    24.          Debug.Log(u.name);
    25.        }
    26.      }
    27.    }
    28. }
    29.  
    Error:
    NullReferenceException: Object reference not set to an instance of an object
    Main.Start () (at Assets/Resources/Scripts/Main.cs:17)
     
  12. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    Just wondering, why do you put them in resources ? Since you're loading everything you might as well have them as normal asset and let unity handle preloading properly.

    This way on top of using a cleaner workflow you can have a public Unit array to feed directly the right objects in.

    If you have many units and want to go deeper in making it clean, you could put the data in a model and have the unit script point to an entry of the model with an id/guid for example (editor scripts can make this very user friendly), this way you wouldn't need to poll prefabs for data about the units. This is clearly out of scope here but if someone reads it and feels confident he can pull it off he should try, it works well :).

    OP if you want to stick to this workflow, add checks to make sure what you loaded is what you expected:

    Code (CSharp):
    1.  GameObject unit = Units[i] as GameObject;
    2.  
    3. if (unit)
    4. {
    5.        Unit u = unit.GetComponent<Unit>();
    6.  
    7.        if (u)
    8.        {
    9.               //your unit data polling here
    10.        }
    11. }
     
  13. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Main : MonoBehaviour {
    6.  
    7.    void Start () {
    8.  
    9.      string path = "Prefabs/Units";  
    10.      Object[] Units = Resources.LoadAll (path);
    11.  
    12.      if(Units.Length > 0){
    13.        for (int i = 0; i < Units.Length; i++)
    14.        {
    15.          GameObject unit = Units[i] as GameObject;
    16.          Debug.Log(unit.name);
    17.          if (unit)
    18.          {
    19.            Unit u = unit.GetComponent<Unit>();
    20.            Debug.Log(u.name);
    21.            if (u) {
    22.              Texture2D unitIcon = u.PMenuIcon;
    23.              Texture2D unitIconRo = u.PMenuIconRo;
    24.  
    25.              Menu.UnitNames.Add (u.name);
    26.              Menu.UnitIconTextures.Add (unitIcon);
    27.              Menu.UnitIconTexturesRo.Add (unitIconRo);
    28.            }
    29.          }
    30.        }
    31.      }
    32.    }
    33. }
    34.  
     
  14. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
    hallo?!?
     
  15. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
  16. DrexonPl

    DrexonPl

    Joined:
    Mar 19, 2015
    Posts:
    14
  17. joa-baur

    joa-baur

    Joined:
    May 14, 2013
    Posts:
    24
    Well, the error message says it all: the Object reference (unit = ...) is not set to AN INSTANCE of a (game)object. resources.load just LOADS stuff, but you have to instantiate a GameObject in order to access its components.

    Take a look at the second example in the API docs to see how it's done :)