Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

I cannot make this script work but I really can't get it.

Discussion in 'Scripting' started by MrMikpik, Feb 7, 2020.

  1. MrMikpik

    MrMikpik

    Joined:
    Dec 11, 2019
    Posts:
    10
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6. using UnityEngine.Audio;
    7. using TMPro;
    8.  
    9.  
    10. public class ButtonManager : MonoBehaviour
    11. {
    12.     int players;
    13.     public int turns;
    14.     public int shotsFired;
    15.     public int maxShots;
    16.     int deadlyShot;
    17.     public TextMeshProUGUI turnText;
    18.     public TextMeshProUGUI shotsFiredText;
    19.     public TextMeshProUGUI maxShotsText;
    20.  
    21.     void Start()
    22.     {
    23.         turnText = GetComponent<TextMeshProUGUI>();
    24.         shotsFiredText = GetComponent<TextMeshProUGUI>();
    25.         maxShotsText = GetComponent<TextMeshProUGUI>();
    26.  
    27.         TurnUpdate();
    28.         turns = 1;
    29.         shotsFired = 0;
    30.         players = PlayerPrefs.GetInt("Players");
    31.         maxShots = PlayerPrefs.GetInt("MaxShots");
    32.         PlayerPrefs.SetInt("P1Points", 0);
    33.         PlayerPrefs.SetInt("P2Points", 0);
    34.         PlayerPrefs.SetInt("P3Points", 0);
    35.         PlayerPrefs.SetInt("P4Points", 0);
    36.     }
    37.  
    38.  
    39.  
    40.     private void TurnUpdate()
    41.     {
    42.         deadlyShot = Random.Range(1, PlayerPrefs.GetInt("MaxShots"));
    43.     }
    44.  
    45.     public void ShootButton()
    46.     {
    47.         shotsFired += 1;
    48.         if (shotsFired == deadlyShot)
    49.         {
    50.             SceneManager.LoadScene(0);
    51.         }
    52.     }
    53.  
    54.     public void StayButton()
    55.     {
    56.         if (PlayerPrefs.GetInt("Players") == 1)
    57.         {
    58.             shotsFired = 0;
    59.             turns += 1;
    60.             TurnUpdate();
    61.         }
    62.     }
    63.  
    64.     private void Update()
    65.     {
    66.         turnText.text = turns.ToString();
    67.         shotsFiredText.text = shotsFired.ToString();
    68.         maxShotsText.text = maxShots.ToString();
    69.     }
    This is my error:
    NullReferenceException: Object reference not set to an instance of an object
    ButtonManager.Update () (at Assets/Scripts/ButtonManager.cs:66)

    (And if I delete the line it's gonna go to the one after that and so on.

    I've done something similar with a previous game, but I used normal text and it worked, so, could be the problem TextMeshPro or is it something else?
     
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Did you connect turnText, shotsFiredText and maxShotsText in Editor to the TextMeshPro objects?
     
  3. MrMikpik

    MrMikpik

    Joined:
    Dec 11, 2019
    Posts:
    10
    Yes, I've done that, but nonetheless it still had the same error.
     
  4. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    The exception tells you that the error is in line 66. Since turns is an integer, the only object that could be null is turnText.
    Since you get the turnText reference by calling GetComponent, are you sure that ButtonManager is on the same object that also has a TextMeshProGUI component? If so, are you sure you dont have two objects with ButtonManagers attached (one of which does not have such a component)? These are the only options i can think off.
    One quick way to check this would also to print a message like the following in Update():
    Code (CSharp):
    1. Debug.Log("Object name: " + gameObject.name + " , component null: " + (turnText == null));
    This way you should quickly see if you have two different scripts running, and if one of them has a null component.
     
  5. MrMikpik

    MrMikpik

    Joined:
    Dec 11, 2019
    Posts:
    10
    Since I had an object without the component, I made up two different scripts:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using TMPro;
    6.  
    7. public class TextManager : MonoBehaviour
    8. {
    9.     public TextMeshProUGUI turnText;
    10.     public TextMeshProUGUI shotsFiredText;
    11.     public TextMeshProUGUI maxShotsText;
    12.     int turnsInt;
    13.     int shotsFiredInt;
    14.     int maxShotsInt;
    15.  
    16.     private void Start()
    17.     {
    18.         turnText = GetComponent<TextMeshProUGUI>();
    19.         shotsFiredText = GetComponent<TextMeshProUGUI>();
    20.         maxShotsText = GetComponent<TextMeshProUGUI>();
    21.     }
    22.  
    23.     void Update()
    24.     {
    25.         turnsInt = GetComponent<ButtonManager>().turns;
    26.         shotsFiredInt = GetComponent<ButtonManager>().shotsFired;
    27.         maxShotsInt = GetComponent<ButtonManager>().maxShots;
    28.  
    29.         turnText.text = turnsInt.ToString();
    30.         shotsFiredText.text = shotsFiredInt.ToString();
    31.         maxShotsText.text = maxShotsInt.ToString();
    32.  
    33.         Debug.LogWarning("Object name: " + gameObject.name + " , component null: " + (turnText == null));
    34.     }
    35. }
    The Text Manager, that I've attached to the TextMeshProUGUI components,

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.UI;
    6. using UnityEngine.Audio;
    7.  
    8.  
    9. public class ButtonManager : MonoBehaviour
    10. {
    11.     int players;
    12.     public int turns;
    13.     public int shotsFired;
    14.     public int maxShots;
    15.     int deadlyShot;
    16.  
    17.     void Start()
    18.     {
    19.  
    20.         TurnUpdate();
    21.         turns = 1;
    22.         shotsFired = 0;
    23.         players = PlayerPrefs.GetInt("Players");
    24.         maxShots = PlayerPrefs.GetInt("MaxShots");
    25.         PlayerPrefs.SetInt("P1Points", 0);
    26.         PlayerPrefs.SetInt("P2Points", 0);
    27.         PlayerPrefs.SetInt("P3Points", 0);
    28.         PlayerPrefs.SetInt("P4Points", 0);
    29.     }
    30.  
    31.  
    32.  
    33.     private void TurnUpdate()
    34.     {
    35.         deadlyShot = Random.Range(1, PlayerPrefs.GetInt("MaxShots"));
    36.     }
    37.  
    38.     public void ShootButton()
    39.     {
    40.         shotsFired += 1;
    41.         if (shotsFired == deadlyShot)
    42.         {
    43.             SceneManager.LoadScene(0);
    44.         }
    45.     }
    46.  
    47.     public void StayButton()
    48.     {
    49.         if (PlayerPrefs.GetInt("Players") == 1)
    50.         {
    51.             shotsFired = 0;
    52.             turns += 1;
    53.             TurnUpdate();
    54.         }
    55.     }
    56.  
    57.     private void Update()
    58.     {
    59.  
    60.     }
    61. }
    And this is the other code, where I got rid of those components.
    But the error is still the same, also no message from the console other than the error.
     
  6. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Since you just split the script into two, the error cannot be the same (at least the line must have changed). Always post the full error message after changes like these, or at least mention what throws which error now if it's still the same kind of error.

    Is it now TextManager.cs:29 which throws the error (which would be the 'same' error)?
    If so, what does the log message print? Is it always the same or does it change?
     
  7. MrMikpik

    MrMikpik

    Joined:
    Dec 11, 2019
    Posts:
    10
    Yeah sorry, you're right. First time using Unity forum so I still have to get the hand of it.

    Anyways the error is:
    NullReferenceException: Object reference not set to an instance of an object
    TextManager.Update () (at Assets/Scripts/TextManager.cs:25)

    The error shows multiple times but I assume it is given to the fact that is in the Update method.
     
  8. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Now the error refers to this line:
    Code (csharp):
    1. turnsInt = GetComponent<ButtonManager>().turns;
    Seems like the ButtonManager is not attached to the object to which your TextManager is attached. Hence GetComponent returns no object and when you use the dot-notation on it, it throws the exception. You need to call GetComponent on the object which holds the component that you are looking for.

    Though I'd recommend that you just assign the references in the inspector. That should be easier right now, as it seems that you might need to get a little more into the GameObject and component system.

    For instance, this part most-likely doesn't do what you want:
    Code (csharp):
    1. turnText = GetComponent<TextMeshProUGUI>();
    2. shotsFiredText = GetComponent<TextMeshProUGUI>();
    3. maxShotsText = GetComponent<TextMeshProUGUI>();
    These calls will return the same component (if any at all), so you assign the return value to three different fields, which are meant to display different values. You most-likely want to have three different components. Same from above applies here: it's easier to assign those in the inspector.
     
  9. MrMikpik

    MrMikpik

    Joined:
    Dec 11, 2019
    Posts:
    10
    Thanks for the in-depth reply.
    In the end tho, I still had error and I had a clumsy workaround, I've changed all TMProUGUI to TMPro, and is weird because it won't be on Canvas but on camera and that's confusing but it worked, even if it wasn't really the optimal solution.