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. Dismiss Notice

Question Game doesn't detect assigned GameObject Reference

Discussion in 'Scripting' started by Happy_Alex-RO, Sep 20, 2023.

  1. Happy_Alex-RO

    Happy_Alex-RO

    Joined:
    Apr 24, 2023
    Posts:
    2
    I'm new to scripting and I learned a bit with the help of ChatGPT, but I can't figure out why my script doesn't work. I'm making a rock paper scissors game with floating objects that attack eachother, and I made a GUI scale option, but when I hit play, I get this error repeating again and again:

    NullReferenceException: Object reference not set to an instance of an object
    menuVals.Update () (at Assets/Scripts/menuVals.cs:68)

    I don't know what's wrong, the references are assigned via the editor, and even if I use GameObject.Find instead of the variables, it still doesn't detect it.


    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 menuVals : MonoBehaviour
    8. {
    9.     public GameObject rockSlider;
    10.     public GameObject paperSlider;
    11.     public GameObject scissorsSlider;
    12.  
    13.     public GameObject rockText;
    14.     public GameObject paperText;
    15.     public GameObject scissorsText;
    16.  
    17.     public GameObject GOBJrockEnabled;
    18.     public GameObject GOBJpaperEnabled;
    19.     public GameObject GOBJscissorsEnabled;
    20.  
    21.     public GameObject uiCanvas;
    22.     public GameObject guiScaleOBJ;
    23.    
    24.     public bool rocksEnabled;
    25.     public bool papersEnabled;
    26.     public bool scissorsEnabled;
    27.  
    28.     private int rocksVal;
    29.     private int papersVal;
    30.     private int scissorsVal;
    31.  
    32.     public int guiScale;
    33.     public int enabledTotal;
    34.  
    35.     private float rawRocksVal, rawPapersVal, rawScissorsVal;
    36.  
    37.     // Start is called before the first frame update
    38.     void Start()
    39.     {
    40.         GOBJrockEnabled.GetComponent<Toggle>().isOn = PlayerPrefs.GetInt("RocksEnabled", 0) == 1;
    41.         GOBJpaperEnabled.GetComponent<Toggle>().isOn = PlayerPrefs.GetInt("PapersEnabled", 0) == 1;
    42.         GOBJscissorsEnabled.GetComponent<Toggle>().isOn = PlayerPrefs.GetInt("ScissorsEnabled", 0) == 1;
    43.  
    44.         rockSlider.GetComponent<Scrollbar>().value = (PlayerPrefs.GetFloat("Rocks", 0.0f));
    45.         paperSlider.GetComponent<Scrollbar>().value = (PlayerPrefs.GetFloat("Papers", 0.0f));
    46.         scissorsSlider.GetComponent<Scrollbar>().value = (PlayerPrefs.GetFloat("Scissors", 0.0f));
    47.     }
    48.  
    49.     // Update is called once per frame
    50.     void Update()
    51.     {
    52.         enabledTotal = 0;
    53.  
    54.         rocksEnabled = GOBJrockEnabled.GetComponent<Toggle>().isOn;
    55.         papersEnabled = GOBJpaperEnabled.GetComponent<Toggle>().isOn;
    56.         scissorsEnabled = GOBJscissorsEnabled.GetComponent<Toggle>().isOn;
    57.        
    58.         if (rocksEnabled == true) {
    59.             enabledTotal++;
    60.         }
    61.         if (papersEnabled == true) {
    62.             enabledTotal++;
    63.         }
    64.         if (scissorsEnabled == true) {
    65.             enabledTotal++;
    66.         }
    67.  
    68.         guiScale = guiScaleOBJ.GetComponent<Dropdown>().value;
    69.         uiCanvas.GetComponent<CanvasScaler>().scaleFactor = guiScale;
    70.  
    71.         rawRocksVal = rockSlider.GetComponent<Scrollbar>().value;
    72.         rawPapersVal = paperSlider.GetComponent<Scrollbar>().value;
    73.         rawScissorsVal = scissorsSlider.GetComponent<Scrollbar>().value;
    74.  
    75.         rocksVal = (int)(rawRocksVal * 124 + 1);
    76.         papersVal = (int)(rawPapersVal * 124 + 1);
    77.         scissorsVal = (int)(rawScissorsVal * 124 + 1);
    78.  
    79.         rockText.GetComponent<TextMeshProUGUI>().text = rocksVal.ToString();
    80.         paperText.GetComponent<TextMeshProUGUI>().text = papersVal.ToString();
    81.         scissorsText.GetComponent<TextMeshProUGUI>().text = scissorsVal.ToString();
    82.  
    83.         PlayerPrefs.SetInt("RocksEnabled", rocksEnabled ? 1 : 0);
    84.         PlayerPrefs.SetInt("PapersEnabled", papersEnabled ? 1 : 0);
    85.         PlayerPrefs.SetInt("ScissorsEnabled", scissorsEnabled ? 1 : 0);
    86.  
    87.         PlayerPrefs.SetFloat("Rocks", rawRocksVal);
    88.         PlayerPrefs.SetFloat("Papers", rawPapersVal);
    89.         PlayerPrefs.SetFloat("Scissors", rawScissorsVal);
    90.     }
    91. }
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Very simple: either
    guiScaleOBJ
    is not assigned in the inspector OR it does not have a Dropdown component on it. Do note that if you're using TextMeshPro (as all projects are doing by default in modern versions of Unity), you likely have a TMP_Dropdown instead of a Dropdown component.

    You can also make your life 50% simpler by directly making references to the components instead of this extremely ugly use of GetComponent all over the place. For example. Instead of:
    Code (CSharp):
    1. public GameObject GOBJrockEnabled;
    and
    Code (CSharp):
    1. GOBJrockEnabled.GetComponent<Toggle>().isOn = PlayerPrefs.GetInt("RocksEnabled", 0) == 1;
    You can just do
    Code (CSharp):
    1. public Toggle RockEnabledToggle;
    and
    Code (CSharp):
    1. RockEnabledToggle.isOn = PlayerPrefs.GetInt("RocksEnabled", 0) == 1;
    This skips a bunch of unecessary gcode and also guarantees that the object will not be missing the component you are looking for since you can only assign it in the inspector when it actually has that component. There's rarely a good reason to use a GameObject reference instead of a direct component reference in Unity. So in this case I would suggest using:
    Code (CSharp):
    1. public TMP_Dropdown guiScaleDropdown;
    and assigning that in the inspector directly.
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
    And you can make it simpler another 50%:

    Turn this liberal sprinkling:

    into a much cleaner access:

    Here's an example of simple persistent loading/saving values using PlayerPrefs:

    https://gist.github.com/kurtdekker/01da815d2dfd336a925ae38019c3a163

    Useful for a relatively small number of simple values.
     
  4. Happy_Alex-RO

    Happy_Alex-RO

    Joined:
    Apr 24, 2023
    Posts:
    2
    Thanks for the help! And also, thanks for letting me know that I can do that to variables.