Search Unity

Question Issue was solved on friday and now im getting the same error

Discussion in 'Scripting' started by Jinngineer, Jul 31, 2020.

  1. Jinngineer

    Jinngineer

    Joined:
    Apr 22, 2020
    Posts:
    41
    Hello,

    I am working on making a UI and i keep getting a null reference error from my script.

    I have searched online for solutions and have come up empty.

    Code (CSharp):
    1.  
    2. public class CoinRotate : MonoBehaviour
    3. {
    4.     Score scoreScript;
    5.     public float RotateSpeed;
    6.  
    7.     // Update is called once per frame
    8.     void Update()
    9.     {
    10.         transform.Rotate(0, RotateSpeed*2, 0);
    11.     }
    12.  
    13.      void OnTriggerEnter(Collider collider)
    14.     {
    15.         if (collider.gameObject.tag=="Player")
    16.         {
    17.             Destroy(gameObject);
    18.             scoreScript.IncrementScore();
    19.         }
    20.     }
    21. }
    22.  
    Code (CSharp):
    1.  
    2. public class Score : MonoBehaviour
    3. {
    4.     int score = 0;
    5.     public Text scoreText;
    6.  
    7.     public void IncrementScore()
    8.     {
    9.         score++;
    10.         scoreText.text = "Score: " + score;
    11.     }
    12. }
    13.  
    So im trying to on contact with my coin to increment the score. But on line:

    Code (CSharp):
    1.  
    2.   scoreScript.IncrementScore();
    3.  
    I keep getting null reference.

    From what i understand about null reference errors, they happen when
    1) you create variable
    2) variable is empty
    3) you try and call variable.

    I do not understand why scoreScript.IncrementScore(); is considered null when it has a value.

    I am also perplexed as i have seen this syntax used to make a UI in tutorials and after rewatching the video a few times i did not notice any issues with my writing.

    Thank you for any assistance you can provide :)

    Best Regards,
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,908
    Your description of the problem is exactly correct, and I'm confused as to where you're getting the idea that
    scoreScript
    has a value. Based on the code you shared: it is a private, nonserialized variable that no value is ever assigned to. How are you verifying that it has a value? How did you initialize that value?

    You may be under the common misconception that simply writing a script creates an instance of that script that can be used in other scripts. This is not the case. The script itself is a blueprint for a type of component. You need to actually create an instance of the component by adding it to a GameObject. ("Add Component" button in the inspector)

    Once you've done that, The simplest way to give your variable a value is to give it a [SerializeField] attribute (or make it public) and drag and drop the GameObject that you added a Score component to from your scene into the inspector slot for the field.
     
    Last edited: Jul 31, 2020
  3. Jinngineer

    Jinngineer

    Joined:
    Apr 22, 2020
    Posts:
    41
    Oooooooo.

    So when i make a new script lets call Script_1, and i want to access it in Script_2. I need to attach Script_1 to a game object, then make a public reference to Script_1 in Script_2 and then attach the Game Object with Script_1 in the inspector.

    I thought that accessing the scipt via code was enough.

    Thanks so much for the help. I am no longer gettig the Error :)
     
    PraetorBlue likes this.
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    The reason is you need to tell it specifically what instance of the class you're talking to, as there could be any number of instances of the script. So setting the reference in the inspector works, but there are other options such as using GetComponent in code.
     
  5. Jinngineer

    Jinngineer

    Joined:
    Apr 22, 2020
    Posts:
    41
    Hello, im back on this thread as the solution that on friday had worked is now showing that it isnt working.

    script 1
    Code (CSharp):
    1.  
    2. public class CoinRotate : MonoBehaviour
    3. {
    4.     public Score scoreScript;
    5.     public float RotateSpeed;
    6.  
    7.     void Start()
    8.     {
    9.        
    10.     }
    11.  
    12.     // Update is called once per frame
    13.     void Update()
    14.     {
    15.         transform.Rotate(0, RotateSpeed*2, 0);
    16.     }
    17.  
    18.      public void OnTriggerEnter(Collider collider)
    19.     {
    20.         if (collider.gameObject.tag=="Player")
    21.         {
    22.             Destroy(gameObject);
    23.             scoreScript.IncrementScore();
    24.         }
    25.     }
    26.  
    27.    
    28. }
    29.  

    script 2
    Code (CSharp):
    1.  
    2.  
    3. public class Score : MonoBehaviour
    4. {
    5.     int score = 0;
    6.     public Text scoreText;
    7.    
    8.  
    9.     public void IncrementScore()
    10.     {
    11.         score++;
    12.        
    13.         scoreText.text = score.ToString();
    14.     }
    15. }
    16.  

    Iam trying to access IncrementScore() in script 1. I am doing this by making a public reference in Script 1 called scoreScript, to the public reference i am attaching the text gameObject which has Script 2 attached.

    An d the issue was solved on friday. But when i re got onto unity today, it was not working and i was getting the same error. For the same line of code.

    I cant understand why the error now returned.
     

    Attached Files:

  6. Goldensnitch

    Goldensnitch

    Joined:
    Nov 4, 2016
    Posts:
    60
    Did you tag your object with "Player"
     
  7. TheOtherUserName

    TheOtherUserName

    Joined:
    May 30, 2020
    Posts:
    136
    You Destroy the Coin before you let it increase the score y´just change the lines (Destroy down and IIncrementScore up) and the error will disapear
     
  8. Jinngineer

    Jinngineer

    Joined:
    Apr 22, 2020
    Posts:
    41
    Yup, the coin gets destroyed. Just i get "NullReferenceException: Object reference not set to an instance of an object" this error. And on froday i thought i had the issue solved just when i started up the game on sat it didnt work anymore.
    And i everything i had done on friday was still saved.
     
  9. Jinngineer

    Jinngineer

    Joined:
    Apr 22, 2020
    Posts:
    41
    Tried that and now the coin wont get destroyed as im having "NullReferenceException: Object reference not set to an instance of an object" on line "scoreScript.IncrementScore();" and im not sure why anymore.
     
  10. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,908
    How are you creating the CoinRotate object?
    Is it instantiated from a prefab?
    How are you populating the "scoreScript" variable?
     
  11. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    That's not actually the case, as a call to Destroy merely schedules the GameObject to be destroyed before the next frame. It stays in the scene for the entirely of the current frame.
     
    Yanne065 and PraetorBlue like this.
  12. Jinngineer

    Jinngineer

    Joined:
    Apr 22, 2020
    Posts:
    41
    Code (CSharp):
    1.  
    2. public class SpawnPlatform : MonoBehaviour
    3. {
    4.     public GameObject platform;
    5.     int Randx, Randy;
    6.     Vector3 pos;
    7.     Vector3 Newpos;
    8.     Vector3 CoinPos;
    9.  
    10.     bool hasBeenTriggered = false;
    11.  
    12.      GameObject myNewPlatform;
    13.     public GameObject Coin;
    14.  
    15.      int CoinToss;
    16.  
    17.     void Update()
    18.     {
    19.         Randx = Random.Range(4, 7);
    20.         Randy = Random.Range(-5, 1);
    21.         pos = transform.position;
    22.         Newpos = pos + new Vector3(Randx, Randy, 0);
    23.  
    24.        
    25.         CoinPos = Newpos + new Vector3(0, 2.5f, 0);
    26.     }
    27.  
    28.     void OnTriggerEnter(Collider other)
    29.     {
    30.         if (other.tag == "Player")
    31.         {
    32.             CoinToss = Random.Range(1, 5);
    33.             spawnNextPlatform();
    34.             spawnCoin();
    35.         }
    36.     }
    37.  
    38.     public void spawnNextPlatform()
    39.     {
    40.         if (!hasBeenTriggered )
    41.         {
    42.             myNewPlatform=Instantiate(platform, Newpos, Quaternion.identity);
    43.         hasBeenTriggered = true;
    44.         }    
    45.     }
    46.  
    47.     private void OnTriggerExit(Collider other)
    48.     {
    49.         Destroy(transform.parent.gameObject);
    50.     }
    51.  
    52.     void spawnCoin()
    53.     {      
    54.         if (CoinToss==1 || CoinToss == 2)
    55.         {
    56.             Instantiate(Coin, CoinPos, Quaternion.identity);
    57.         }
    58.     }
    59. }
    60.    
    61.  
    I am instantiating the object from a prefab.

    The Score script attached as in the picture i added.
     

    Attached Files:

  13. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,908
    When you spawn your coin you need to give it a reference to the score script somehow. One way would be to give your ScoreText object from your screenshot a "Score" tag. Then you can do this in your coin script:
    Code (CSharp):
    1. public class CoinRotate : MonoBehaviour
    2. {
    3.     Score scoreScript;
    4.  
    5.     void Start() {
    6.        if (!scoreScript) scoreScript = GameObject.FindObjectWithTag("Score").GetComponent<Score>();
    7.     }
    Another way would be to give your ScorePlatform a reference to the score script...
    Code (CSharp):
    1. public class SpawnPlatform : MonoBehaviour
    2. {
    3.     // Assign this to the ScoreText object in the inspector
    4.     public Score scoreScript;
    And then when you instantiate the coin, you pass that reference on:
    Code (CSharp):
    1.     void spawnCoin()
    2.     {  
    3.         if (CoinToss==1 || CoinToss == 2)
    4.         {
    5.             var coin = Instantiate(Coin, CoinPos, Quaternion.identity);
    6.             coin.GetComponent<CoinRotate>().scoreScript = this.scoreScript;
    7.         }
    8.     }