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

Null Reference Solution Needed...

Discussion in 'Scripting' started by Alismadia, Oct 13, 2016.

  1. Alismadia

    Alismadia

    Joined:
    Jan 26, 2015
    Posts:
    20
    Hello,
    I have been struggling with this issue for a couple of days and tried 100+ different solutions... but I still keep coming back to this simple line of code:

    public class EnemyTracker : MonoBehaviour
    {

    Transform enemySeek;

    void Update ()
    {
    enemySeek = GameObject.FindGameObjectWithTag("Enemy").transform;
    transform.position = new Vector2(enemySeek.position.x, enemySeek.position.y);
    }
    }

    It does what I want very well.. it seeks out all the enemies of the type and instantly destroys them when unleashed on the enemy (and somehow decides to do it in the order that the objects are instantiated...). However, because I am trying to find the enemies using their transform, as soon as there are no enemies left, the transform line sends a Null Reference Error to the console. I have tried to make it so that if enemySeek returns null then the object is destroyed, but that doesn't work.... I have also tried playing around with the idea of using Lists and things of this nature, but this doesn't seem to work either (though I am not great at understanding the syntax with Lists yet, so maybe I am just doing it wrong..)

    Either way, no matter what solution I have tried thus far, I cannot prevent the null reference from firing off once all enemies are destroyed... I need to fix this so that I can get on with my life.. can someone please help me??
     
  2. imDanOush

    imDanOush

    Joined:
    Oct 12, 2013
    Posts:
    368
    Try the code below.
    Code (CSharp):
    1.  
    2. public class EnemyTracker : MonoBehaviour
    3. {
    4.     Transform enemySeek = null;
    5.  
    6.     void Update ()
    7.       {
    8.           GameObject gO = GameObject.FindGameObjectWithTag("Enemy");
    9.           if (gO!=null){
    10.               enemySeek = gO.GetComponent<Transform>();
    11.               //foo
    12.            }
    13.       }
    14. }
    15.  
    I just wrote it on the fly (so I didn't test it) but it should work,though. I mean you get the idea, you should first check if the game object is present then get the transform component. And always insert your code in the "code tag" instead of writing it here in this forum. This way the code looks much better looking and easier to read.
     
    Last edited: Oct 13, 2016
  3. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    I suggest, as a matter of convenience, to never chain your member calls.

    For example, the line
    Code (csharp):
    1. enemySeek = GameObject.FindGameObjectWithTag("Enemy").transfrom
    has two member calls. The first methodcall is FindGameObjectWithTag(...). The second is accessing the transform property. I suspect that, in this specific case, your null value is coming from the transform access. It's a simple fix.

    Code (csharp):
    1. var enemySeekGO = GameObject.FindGameObjectWithTag("Enemy");
    2. if (enemySeekGO != null)
    3. {
    4.     enemySeek = enemySeekGO.transform;
    5. }
    6. else
    7. {
    8.     enemySeek = null;
    9. }
    This type of coding is suggested practice.
     
  4. Alismadia

    Alismadia

    Joined:
    Jan 26, 2015
    Posts:
    20
    Hazzah! Alright Team Thank You Very Much!!. We have achieved a successful shooting solution. It is a bit of all of our efforts combined, and this is what it looks like:

    Code (csharp):
    1.  
    2. public class EnemyTracker : MonoBehaviour
    3. {
    4.   void Update ()
    5.   {
    6.   var enemyTracker = GameObject.FindGameObjectWithTag("Enemy");
    7.   if (enemyTracker != null)
    8.   {
    9.   transform.position = new Vector2(enemyTracker.transform.position.x, enemyTracker.transform.position.y);
    10.   }
    11.   else
    12.   {
    13.   enemyTracker = null;
    14.   }
    15.   }
    16. }
    17.  
     
  5. Kalladystine

    Kalladystine

    Joined:
    Jan 12, 2015
    Posts:
    227
    Since you're not storing enemyTracker, you don't need the else part.

    Storing it would be a good idea though, to not need to call Find every frame (and also risk finding a different enemy while this one is still alive, if the hierarchy gets shuffled).

    Something like:
    Code (CSharp):
    1. public class EnemyTracker : MonoBehaviour
    2. {
    3.     private GameObject enemyTracked;
    4.  
    5.     void Update()
    6.     {
    7.         if (!enemyTracked)
    8.         {
    9.             enemyTracked = GameObject.FindGameObjectWithTag("Enemy");
    10.         }
    11.         else
    12.         {
    13.             transform.position = new Vector2(enemyTracked.transform.position.x, enemyTracked.transform.position.y);
    14.         }
    15.     }
    16. }
     
  6. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Looking forward to the day we get null conditional operators.
     
    Kalladystine likes this.