Search Unity

NullReferenceException: Object reference not set to an instance of an object

Discussion in 'Scripting' started by maryus799, Feb 3, 2017.

  1. maryus799

    maryus799

    Joined:
    Feb 3, 2017
    Posts:
    5
    I' try to make a spaceshooter game and i want to respawn ship after collider with an object. I'm new in programming and i will be very glad if you can help me with some indications. I'm still learning. Thanks alot!
    This is my code. I have problem at this line:
    respawnPosition.position = GameObject.FindGameObjectWithTag("Player").transform.position;


    using UnityEngine;
    using System.Collections;

    public class DestroyByAsteroid : MonoBehaviour
    {
    public GameObject explosion;
    public GameObject playerExplosion;
    public int scoreValue;
    private GameController gameController;
    private Transform respawnPosition = null;


    void Start()
    {
    GameObject gameControllerObject = GameObject.FindWithTag("GameController");

    if(gameControllerObject!=null)
    {
    gameController = gameControllerObject.GetComponent < GameController>();
    }

    if(gameController==null)
    {
    Debug.Log("Cannot find 'GameController' script");
    }

    respawnPosition.position = GameObject.FindGameObjectWithTag("Player").transform.position;
    }

    void OnTriggerEnter(Collider other)
    {
    if (other.tag == "Boundary" || other.tag=="Option")
    {
    return;
    }

    Instantiate(explosion, transform.position, transform.rotation);


    if (other.tag == "Player")
    {
    Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
    other.transform.position = respawnPosition.transform.position;
    gameController.GameOver();
    }

    gameController.AddScore(scoreValue);
    Destroy(other.gameObject);
    Destroy(gameObject);

    }
    }
     
  2. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    First of all, you should use Code tags.

    As for the problem, you never instantiate 'respawnPosition'. I see it is a private Transform field which is never properly instantiated too.

    I guess what you want is set the position of the player as the respawnposition on Start, in which case you should change that line too:
    Code (CSharp):
    1. respawnPosition= GameObject.FindGameObjectWithTag("Player").transform;
    Edit: If you are new too Unity and programming in general, I advise you to go through the learn section. Next to that some general knowledge of C# will also help you out in the long run, and for that I advise you to go through the videos C# for beginners tutorials from Quill18 for which the link is in my signature.Or if you learn easier from books, I can suggest the C# programming yellow book (it has cheese).
     
  3. maryus799

    maryus799

    Joined:
    Feb 3, 2017
    Posts:
    5
    Thanks! I have basic knowledges of c++ and c# but i used them for the first time in unity. I don't understand why "you never instantiate 'respawnPosition'" because i need respawnPosition later .... i will go to learn section and i will have some answers :)
     
  4. maryus799

    maryus799

    Joined:
    Feb 3, 2017
    Posts:
    5
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DestroyByAsteroid : MonoBehaviour
    5. {
    6. public GameObject explosion;
    7. public GameObject playerExplosion;
    8. public int scoreValue;
    9. private GameController gameController;
    10. private Transform respawnPosition = null;
    11.  
    12.  
    13. void Start()
    14. {
    15. GameObject gameControllerObject = GameObject.FindWithTag("GameController");
    16.  
    17. if(gameControllerObject!=null)
    18. {
    19. gameController = gameControllerObject.GetComponent < GameController>();
    20. }
    21.  
    22. if(gameController==null)
    23. {
    24. Debug.Log("Cannot find 'GameController' script");
    25. }
    26.  
    27. respawnPosition.position = GameObject.FindGameObjectWithTag("Player").transform.position;
    28. }
    29.  
    30. void OnTriggerEnter(Collider other)
    31. {
    32. if (other.tag == "Boundary" || other.tag=="Option")
    33. {
    34. return;
    35. }
    36.  
    37. Instantiate(explosion, transform.position, transform.rotation);
    38.  
    39.  
    40. if (other.tag == "Player")
    41. {
    42. Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
    43. other.transform.position = respawnPosition.transform.position;
    44. gameController.GameOver();
    45. }
    46.  
    47. gameController.AddScore(scoreValue);
    48. Destroy(other.gameObject);
    49. Destroy(gameObject);
    50.  
    51. }
    52. }
     
  5. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    Well, what you are doing (fe on line 27 above) is you try to set the position of the respawnPosition object directly, while the respawnPosition object is still null, which wil not work. If you set respawnPositon to be the players transform instead, your code should work (or at least your current error will go away). You don't need to set the position directly, just set the transform and you're done.
     
  6. maryus799

    maryus799

    Joined:
    Feb 3, 2017
    Posts:
    5
    You are right, but the same error i have when i change the code. The error appears after my spaceship is destroyed and the respawn doesn't work. I attached my new code.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DestroyByAsteroid : MonoBehaviour
    5. {
    6.     public GameObject explosion;
    7.     public GameObject playerExplosion;
    8.     public int scoreValue;
    9.     private GameController gameController;
    10.     private Transform respawnPosition;
    11.     void Start()
    12.     {
    13.         GameObject gameControllerObject = GameObject.FindWithTag("GameController");
    14.  
    15.         if(gameControllerObject!=null)
    16.         {
    17.             gameController = gameControllerObject.GetComponent < GameController>();
    18.         }
    19.  
    20.         if(gameController==null)
    21.         {
    22.             Debug.Log("Cannot find 'GameController' script");
    23.         }
    24.         respawnPosition= GameObject.FindGameObjectWithTag("Player").transform;
    25.     }
    26.  
    27.     void OnTriggerEnter(Collider other)
    28.     {
    29.         if (other.tag == "Boundary")
    30.         {
    31.             return;
    32.         }
    33.         Instantiate(explosion, transform.position, transform.rotation);
    34.  
    35.         if (other.tag == "Player")
    36.         {
    37.             Instantiate(playerExplosion, other.transform.position, other.transform.rotation);
    38.      
    39.             Destroy(gameObject);
    40.             Destroy(other.gameObject);
    41.             other.transform.position = respawnPosition.position;
    42.         }
    43.         gameController.AddScore(scoreValue);      
    44.     }
    45. }

    And this is the error:
    NullReferenceException: Object reference not set to an instance of an object
    DestroyByAsteroid.Start () (at Assets/scripts/DestroyByAsteroid.cs:24)
     
  7. maryus799

    maryus799

    Joined:
    Feb 3, 2017
    Posts:
    5
    I think "other.transform.position= respawnPosition.position;" is not good and i tried to instantiante with Vector3.zero, but the same result.
     
  8. Timelog

    Timelog

    Joined:
    Nov 22, 2014
    Posts:
    528
    At line 24 you do:
    Code (CSharp):
    1. GameObject.FindGameObjectWithTag("Player")
    Which will return null if you destroy that gameObject. Try to just disable the player object instead of destroying it when the player dies, then you can keep a reference around, and just re-enable the gameobject when respawning.

    I believe the spaceshooter tutorial in the learn section also does that.
     
    maryus799 likes this.