Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Question Trouble with NullReferenceException (I tried everything)

Discussion in 'Scripting' started by Trussmister, May 12, 2024.

  1. Trussmister

    Trussmister

    Joined:
    Mar 24, 2024
    Posts:
    24
    Hi, I have written a line of code that controls wether a flare gun appears or not, but i referenced a variable on another piece of code on a game manager game object and it bugs out, i even tried to make it a static variable and didn't work. Code attached below, thanks.
    Code (CSharp):
    1. private ItemManager items;
    2.     // Update is called once per frame
    3.     void Start()
    4.     {
    5.         items = GameObject.Find("GameManager").GetComponent<ItemManager>();
    6.     }
    7.     void Update ()
    8.     {
    9.         if (items.HasFlareGun == true)
    10.         {
    11. activateFlare();
    12. }
    13. else
    14. {
    15. gameObject.SetActive(false);
    16. }
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    7,000
    Have you tried debugging your code?

    Alternatively: search for Kurt Dekker's "The answer is always the same .. ALWAYS."

    As well as: when you should be using GameObject.Find. Hint: the a
    nswer is always never!
     
  3. Trussmister

    Trussmister

    Joined:
    Mar 24, 2024
    Posts:
    24
    Oh, sorry, im quite new and didn't know that was a feature, thanks.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,412
    You never need to attach code for NullReferenceExceptions.

    You don't even need to post because it won't help. It's NOT one of the steps that fix NullReferenceExceptions.

    You also don't need to "try everything." You only need to do the following three steps.

    The answer is always the same... ALWAYS!

    How to fix a NullReferenceException error

    https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

    Three steps to success:
    - Identify what is null <-- any other action taken before this step is WASTED TIME
    - Identify why it is null
    - Fix that
     
  5. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,752
    I really want to smack the people making the tutorials showing
    Find
    . It's an absolutely awful way to access an object as it's extremely prone to null reference errors if anything is the slightest bit off, and depending on scene complexity can be anywhere from a few times slower to hundreds of times slower. It can take seconds per call.

    If you have a single instance of an object in a scene that you need to access the simplest approach is to have the object provide the reference for you and then whenever you need to access the object you simply query the static field holding the instance reference.

    Modify your class to add the following code:
    Code (csharp):
    1. public class ItemManager : MonoBehaviour
    2. {
    3.     private static ItemManager _Instance; // reference field (static makes it so only one copy of the field exists for all instances)
    4.     public static ItemManager Instance => _Instance; // makes it read-only to avoid modifying by accident
    5.  
    6.     private void Awake()
    7.     {
    8.         if (_Instance != null) // if the first one was already found delete any accidental second copies
    9.         {
    10.             DestroyImmediate(gameObject);
    11.         }
    12.         else // finds the first instance, assigns the reference field, and makes it persist through scenes
    13.         {
    14.             _Instance = this;
    15.             DontDestroyOnLoad(gameObject); // remove if you don't want it to persist between scene loads
    16.         }
    17.     }
    18. }
    Accessing:
    Code (csharp):
    1. items = ItemManager.Instance;
     
    Last edited: May 12, 2024
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,412
    I love ya Ryiah but I gotta say I feel the same way about the above code you posted.

    If something is DontDestroyOnLoad, it should NEVER NEVER NEVER NEVER NEVER be placed in a scene.

    NEVER!

    Doing so opens you immediately to many possible failures:

    1. it WASN'T in the brand-new scene you made to test some little thing three months from now
    2. it WAS in the scene but the scene changed and it was referring to something that got deleted when you loaded a new scene

    Just DON'T EVER drop things in the scene if they are to be marked DontDestroyOnLoad.

    No exceptions. Don't do it. EVER. It's WAY worse than using GameObject.Find().

    Instead, move up the food chain... evolve. Use this pattern:

    Simple Singleton (UnitySingleton):

    Some super-simple Singleton examples to take and modify:

    Simple Unity3D Singleton (no predefined data):

    https://gist.github.com/kurtdekker/775bb97614047072f7004d6fb9ccce30

    Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

    https://gist.github.com/kurtdekker/2f07be6f6a844cf82110fc42a774a625

    These are pure-code solutions, DO NOT put anything into any scene, just access it via .Instance

    Alternately you could start one up with a
    RuntimeInitializeOnLoad
    attribute.
     
    Ryiah likes this.
  7. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,752
    Haha, that's fair. I don't use the manual approach myself but we weren't told anything about their manager and I was worried about overwhelming them in the event that they're setting data in the manager and would need the prefab variant. I don't actually know how complex it is from a beginner's perspective.
     
    Kurt-Dekker likes this.