Search Unity

NullReferenceException that shouldn't exist!

Discussion in 'Scripting' started by NotTimTam, Dec 10, 2018.

  1. NotTimTam

    NotTimTam

    Joined:
    Sep 24, 2015
    Posts:
    20
    I am making a multiplayer fps game loosely based off of brackey's tutorial. I cannot show all the scripts because I don't want people copying my code...

    I get a reference exception whenever I open the game-selection scene. Here is the error:

    NullReferenceException: Object reference...... blablabla

    I look at the script: (just posting that section)

    Code (CSharp):
    1. IEnumerator sendGetDataRequest(string username, string password, OnDataReceivedCallback onDataReceived)
    2.     {
    3.         string data = "ERROR";
    4.  
    5.         IEnumerator eeee = DCF.GetUserData(username, password);
    6.         while (eeee.MoveNext())
    7.         {
    8.             yield return eeee.Current;
    9.         }
    10.         WWW returnedddd = eeee.Current as WWW;
    11.         if (returnedddd.text != "Error") // ERROR HERE!!!
    12.         {
    13.             if (returnedddd.text == "ContainsUnsupportedSymbol")
    14.             {
    15.                 //One of the parameters contained a - symbol
    16.                 Debug.Log("Get Data Error: Contains Unsupported Symbol '-'");
    17.             }
    18.             else
    19.             {
    20.                 //Data received in returned.text variable
    21.                 string DataRecieved = returnedddd.text;
    22.                 data = DataRecieved;
    23.             }
    24.         }
    25.         else
    26.         {
    27.             //Error occurred. For more information of the error, DC.Login could
    28.             //be used with the same username and password
    29.             Debug.Log("Data Download Error. Try again in a few minutes. If problem still occurs, contact us on DISCORD.");
    30.         }
    31.  
    32.         if (onDataReceived != null)
    33.             onDataReceived.Invoke(data);
    34.     }
    35.  
    36. }
    the error is on line 108 (if (returnedddd.text != "Error"))

    But that is an if statement, and the object it defines is instantiated right above that if statment. Do what you can with what I gave you... Thanks..
     
  2. NotTimTam

    NotTimTam

    Joined:
    Sep 24, 2015
    Posts:
    20
    Line 108 is line 11 here...
     
  3. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Then right before your if statement you should do debug.log to print out what returnedddd.text is to see if it is returning null. Also can't hurt to print out what returnedddd value is as well. Just because you created it doesn't mean it doesn't have a null value.
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    Sure the WWW variable is declared right above it. But you have it set to the IEnumerator.Current value that you just finished looping in the 'while' loop before that.

    When an enumerator finishes its last 'MoveNext' and returns false, it also sets its Current property to null. You're not getting anything out of it. (or at least that's the default behaviour for most enumerators, including iterator functions... but since IEnumerator is an interface it technically depends on the implementor and how it behaves)

    Now from looking at your logic, I presume your enumerator that you're while looping should return a WWW as its last member. Set that to some variable during the while loop. Also, since there is no guarantee that this is so (since DCF.GetUserData is just returning an IEnumerator)... you should probably also test to make sure that it was a WWW. Unless that is DCF.GetUserData can guarantee this, in which case it probably should be defined as such as part of its shape/interface... but alas, I do not know your implementation of DCF.GetUserData since:

    I assure you, we're not all here to steal your code.
     
    Brathnann likes this.
  5. Deleted User

    Deleted User

    Guest

    Or people could come here and tell you how to make it better... but it's up to you.
     
  6. NotTimTam

    NotTimTam

    Joined:
    Sep 24, 2015
    Posts:
    20
    thanks guys I will try it!
     
  7. NotTimTam

    NotTimTam

    Joined:
    Sep 24, 2015
    Posts:
    20
    Mind if I put your usernames in the credits under special thanks. Since technically, you just helped with development?
     
  8. NotTimTam

    NotTimTam

    Joined:
    Sep 24, 2015
    Posts:
    20
    heres the whole script lordofduct
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using DatabaseControl;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class UserAccountManager : MonoBehaviour
    7. {
    8.  
    9.     public static UserAccountManager instance;
    10.  
    11.     void Awake()
    12.     {
    13.         if (instance != null)
    14.         {
    15.             Destroy(gameObject);
    16.             return;
    17.         }
    18.  
    19.         instance = this;
    20.         DontDestroyOnLoad(this);
    21.     }
    22.  
    23.     public static string LoggedIn_Username { get; protected set; } //stores username once logged in
    24.     private static string LoggedIn_Password = ""; //stores password once logged in
    25.  
    26.     public static bool IsLoggedIn { get; protected set; }
    27.  
    28.     public string loggedInSceneName = "Lobby";
    29.     public string loggedOutSceneName = "LoginMenu";
    30.  
    31.     public delegate void OnDataReceivedCallback(string data);
    32.  
    33.     public void LogOut()
    34.     {
    35.         LoggedIn_Username = "";
    36.         LoggedIn_Password = "";
    37.  
    38.         IsLoggedIn = false;
    39.  
    40.         Debug.Log("Logged out!");
    41.  
    42.         SceneManager.LoadScene(loggedOutSceneName);
    43.     }
    44.  
    45.     public void LogIn(string username, string password)
    46.     {
    47.         LoggedIn_Username = username;
    48.         LoggedIn_Password = password;
    49.  
    50.         IsLoggedIn = true;
    51.  
    52.         Debug.Log("Logging in as " + username);
    53.  
    54.         SceneManager.LoadScene(loggedInSceneName);
    55.     }
    56.  
    57.     public void SendData(string data)
    58.     { //called when the 'Send Data' button on the data part is pressed
    59.         if (IsLoggedIn)
    60.         {
    61.             //ready to send request
    62.             StartCoroutine(sendSendDataRequest(LoggedIn_Username, LoggedIn_Password, data)); //calls function to send: send data request
    63.         }
    64.     }
    65.  
    66.     IEnumerator sendSendDataRequest(string username, string password, string data)
    67.     {
    68.         IEnumerator eee = DCF.SetUserData(username, password, data);
    69.         while (eee.MoveNext())
    70.         {
    71.             yield return eee.Current;
    72.         }
    73.         WWW returneddd = eee.Current as WWW;
    74.         Debug.Log("Okay at 74 (DEBUGGING)");
    75.         if (returneddd.text == "ContainsUnsupportedSymbol")
    76.         {
    77.             //One of the parameters contained a - symbol
    78.             Debug.Log("Data Upload Error: Could be a server error. Try again in a few minutes. If problem still occurs, contact us on DISCORD.");
    79.         }
    80.         if (returneddd.text == "Error")
    81.         {
    82.             //Error occurred. For more information of the error, DC.Login could
    83.             //be used with the same username and password
    84.             Debug.Log("Data Upload Error: Contains Unsupported Symbol '-'");
    85.         }          
    86.     }
    87.  
    88.     public void GetData(OnDataReceivedCallback onDataReceived)
    89.     { //called when the 'Get Data' button on the data part is pressed
    90.  
    91.         if (IsLoggedIn)
    92.         {
    93.             //ready to send request
    94.             StartCoroutine(sendGetDataRequest(LoggedIn_Username, LoggedIn_Password, onDataReceived)); //calls function to send get data request
    95.         }
    96.     }
    97.  
    98.     IEnumerator sendGetDataRequest(string username, string password, OnDataReceivedCallback onDataReceived)
    99.     {
    100.         string data = "ERROR";
    101.  
    102.         IEnumerator eeee = DCF.GetUserData(username, password);
    103.         while (eeee.MoveNext())
    104.         {
    105.             yield return eeee.Current;
    106.         }
    107.         WWW returnedddd = eeee.Current as WWW;
    108.         Debug.Log("")
    109.         if (returnedddd.text != "Error")
    110.         {
    111.             if (returnedddd.text == "ContainsUnsupportedSymbol")
    112.             {
    113.                 //One of the parameters contained a - symbol
    114.                 Debug.Log("Get Data Error: Contains Unsupported Symbol '-'");
    115.             }
    116.             else
    117.             {
    118.                 //Data received in returned.text variable
    119.                 string DataRecieved = returnedddd.text;
    120.                 data = DataRecieved;
    121.             }
    122.         }
    123.         else
    124.         {
    125.             //Error occurred. For more information of the error, DC.Login could
    126.             //be used with the same username and password
    127.             Debug.Log("Data Download Error. Try again in a few minutes. If problem still occurs, contact us on DISCORD.");
    128.         }
    129.  
    130.         if (onDataReceived != null)
    131.             onDataReceived.Invoke(data);
    132.     }
    133.  
    134. }
     
  9. NotTimTam

    NotTimTam

    Joined:
    Sep 24, 2015
    Posts:
    20
     do debug.log to print out what returnedddd.text is to see if it is returning null.


    Result: Returns Null

    what exactly am I supposed to change now.
     
  10. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    Not necessary... this sort of assistance is what forums are for.

    They were suggesting you use a Debug.Log to see what returneddd.text spat out. They thought maybe the text was coming back null.

    Thing is, this is inconsequential. Comparing a null string to "Error!" doesn't throw an exception. You're not directly accessing members of 'text', so it doesn't matter if it were null.

    And that's because, as was pointed out, your null object was the 'returneddd' in and of itself.

    How you'd really deal with it is something along the lines of:
    Code (csharp):
    1.  
    2.     IEnumerator sendGetDataRequest(string username, string password, OnDataReceivedCallback onDataReceived)
    3.     {
    4.         string data = "ERROR";
    5.  
    6.         IEnumerator eeee = DCF.GetUserData(username, password);
    7.         WWW returnedddd = null;
    8.         while (eeee.MoveNext())
    9.         {
    10.             returnedddd = eeee.Current as WWW;
    11.             yield return eeee.Current;
    12.         }
    13.      
    14.         if (returnedddd != null && returnedddd.text != "Error") // ERROR HERE!!!
    15.         {
    16.  
    Though personally I find this to be code smell, and that code smell is creeping out of the DCF.GetUserData method. Personally I'd be refactoring that method so that you could cleanly access the WWW object from it.

    ...

    On a tangent... what is up with the 'eeee' and 'dddd' and what not in your variable names? I've seen some weird naming conventions over the many years I've been coding... and that one is a first for me.
     
    Last edited: Dec 10, 2018
  11. NotTimTam

    NotTimTam

    Joined:
    Sep 24, 2015
    Posts:
    20
    You've been awesome lordofduct... Thanks...