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

Bug Object Reference not set to an instance of an object

Discussion in 'Scripting' started by Wensleydale, Aug 21, 2023.

  1. Wensleydale

    Wensleydale

    Joined:
    Aug 21, 2023
    Posts:
    4
    Hi,
    This is my first ever forum post on here or any forum for that matter so please be patient if I miss things out that seem obvious :)

    I've been getting these errors recently. I've fixed one by instantiating the object that was being referenced as it hadn't yet been. That fix made sense and I thought the other would follow suit. Unfortunately that wasn't the case and I cannot figure out what I'm doing wrong.

    I'm new to Unity and c# so maybe there is a major misunderstanding but I hope not.

    The Issue:

    The error is on line 25 of my GameBoardScript which controlls the behaviour of a game board (2D array of tiles)
    upload_2023-8-21_17-45-20.png

    The order of execution is as follows:

    The game manager starts and creates a rider and puts it into a list of riders.
    After that it creates the game board
    upload_2023-8-21_17-46-32.png

    the game manager has a method for getting the rider

    upload_2023-8-21_17-49-8.png

    I don't unserstand what's happening because as far as I can see by the time I create the game board the rider has been instantiated, so when the start method of GameBoardScript tries to GetMainRider, it should work. Any help would be greatly appreciated :)
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    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

    Then you probably have not completed Step #1.

    Also, for future reference:

    If you post a code snippet, ALWAYS USE CODE TAGS:

    How to use code tags: https://forum.unity.com/threads/using-code-tags-properly.143875/

    - Do not TALK about code without posting it.
    - Do NOT post unformatted code.
    - Do NOT retype code. Use copy/paste properly using code tags.
    - Do NOT post screenshots of code.
    - Do NOT post photographs of code.
    - ONLY post the relevant code, and then refer to it by line in your discussion.
     
  3. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    It's best to copy code and paste it into code tags:
    https://forum.unity.com/threads/using-code-tags-properly.143875/
    That way it's easier for us to copy/fix/paste.

    Not sure why you Instantiate as GameObject, as Instantiation is already creating a gameObject.

    Also you're declaring both of these things in Start(), so you have no way to be sure which one is reading first. With the null error I will assume GameBoardScript is reading first, then GameManagerScript reads after that.

    And I know you're a beginner, so I'll be nice, lol, but you are completely beating-around-the-bush with your code. As far going through all that, that's a bit of an undertaking. So I'll link this post I had yesterday, and skim through it and see if you can pick up a few better ways to do things. :)
    https://forum.unity.com/threads/argumentnullexception-value-cannot-be-null.1481625/#post-9237327
     
    Wensleydale likes this.
  4. Wensleydale

    Wensleydale

    Joined:
    Aug 21, 2023
    Posts:
    4
    Thanks for the help, both of you

    So I've changed the methods to awake to ensure the initialisation order is good, which it is.

    I've followed the steps on finding the null reference fix. Debugged through the code and what I have found has just confused me even more.

    I know you said to post the code itself but for the purposng of the debugging info I'm going to include 2 screenshots

    So the null reference is here. rider is null because of another null reference within it's awake function (I believ),
    upload_2023-8-22_17-3-31.png

    The null reference within Rider is that GMScript is null
    upload_2023-8-22_17-14-16.png

    I'm not really understanding why it would be complaining about that being Null. This is me initialising the variable so I'm expecting it to be null. Rider is definetley not null as I've been initalising that prefab successfully.

    Code below:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GameManagerScript : MonoBehaviour
    6. {
    7.     private List<GameObject> riders;
    8.     private GameObject rider;
    9.  
    10.     public GameObject MainCamera;
    11.     public GameObject Rider;
    12.     public GameObject GameBoard;
    13.  
    14.  
    15.  
    16.  
    17.     RiderScript riderScript;
    18.     // Start is called before the first frame update
    19.     void Awake ()
    20.     {
    21.         Debug.Log("GameManager Awake ----------");
    22.         GameObject camera = Instantiate(MainCamera, new Vector3(0,0,-10), transform.rotation);
    23.  
    24.         riders = new List<GameObject>();
    25.         rider = Instantiate(Rider, new Vector3(1, 1, 0), transform.rotation);
    26.         riders.Add(rider);
    27.         Debug.Log(" ----------");
    28.         GameObject gameBoard = Instantiate(GameBoard, new Vector3(0, 0, 0), transform.rotation);
    29.         //Fetching all the relevant scripts that we are going to be using
    30.        riderScript = rider.GetComponent<RiderScript>();
    31.  
    32.     }
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public enum Direction
    5. {
    6.     None,
    7.     Right,
    8.     Left,
    9.     Up,
    10.     Down
    11. }
    12. public class RiderScript : MonoBehaviour
    13. {
    14.     GameManagerScript GMScript;
    15.     private Direction direction = Direction.None;
    16.     private Direction previousDirection;
    17.     public int stepSize;
    18.  
    19.  
    20.     // Start is called before the first frame update
    21.     void Awake()
    22.     {
    23.         Debug.Log("Rider Awake ----------");
    24.         GMScript = GameObject.FindGameObjectWithTag("GameManager").GetComponent<GameManagerScript>();
    25.     }
     
  5. Wensleydale

    Wensleydale

    Joined:
    Aug 21, 2023
    Posts:
    4
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Let's clean up your names a bit. You have
    rider
    ,
    riders
    and
    Rider


    Don't do that. Just... don't.

    How about:

    Rider
    ->
    RiderPrefab


    rider
    ->
    riderInstance


    riders
    ->
    allRiders


    Now... if you only have one of these rider things, why do you need a list of them?

    Also: why are you keeping them by GameObject AND by RiderScript? Pick one.

    Keeping things as a RiderScript should suffice for everything. You can always use the .gameObject shortcut on the RiderScript reference.

    AND... who is calling GetMainRider() and how do you KNOW they are never calling that before your Awake() runs?

    So start sprinkling Debug.Log()s around because the computer is always correct on NullRefs.

    Time to start debugging! Here is how you can begin your exciting new debugging adventures:

    You must find a way to get the information you need in order to reason about what the problem is.

    Once you understand what the problem is, you may begin to reason about a solution to the problem.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling
    Debug.Log()
    statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the names of the GameObjects or Components involved?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as
    Debug.Log("Problem!",this);


    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer for iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    If your problem is with OnCollision-type functions, print the name of what is passed in!

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    "When in doubt, print it out!(tm)" - Kurt Dekker (and many others)

    Note: the
    print()
    function is an alias for Debug.Log() provided by the MonoBehaviour class.

    ----------------------------

    Referencing variables, fields, methods (anything non-static) in other script instances:

    https://forum.unity.com/threads/hel...-vars-in-another-script.1076825/#post-6944639

    https://forum.unity.com/threads/accessing-a-gameobject-in-different-scene.1103239/

    It isn't always the best idea for everything to access everything else all over the place. For instance, it is BAD for the player to reach into an enemy and reduce his health.

    Instead there should be a function you call on the enemy to reduce his health. All the same rules apply for the above steps: the function must be public AND you need a reference to the class instance.

    That way the enemy (and only the enemy) has code to reduce his health and simultaneously do anything else, such as kill him or make him reel from the impact, and all that code is centralized in one place.
     
  7. Wensleydale

    Wensleydale

    Joined:
    Aug 21, 2023
    Posts:
    4
    I had another look and my Tag was wrong : /

    I added some trace to check the running sequence and it was all in the right order.

    There will be more riders in the future, that's the reason for the list.

    Good name suuggestions, I'll change those

    I did not know you could get an object from the script reference, I will do that from now on, thanks
     
    Last edited: Aug 22, 2023
  8. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    a way to cut up code to see each piece:
    Code (CSharp):
    1. void Awake()
    2. {
    3.     Debug.Log("Rider Awake ----------");
    4.     GameObject obj = GameObject.FindGameObjectWithTag("GameManager");
    5.     Debug.Log($"game manager = {obj.name}"); // debug seeing if object was found
    6.     GMScript = obj.GetComponent<GameManagerScript>();
    7. }
    And if this call is null?
    rider = Instantiate(Rider, new Vector3(1, 1, 0), transform.rotation);

    then "Rider" was not set in the inspector, or found before hand with code
     
    Wensleydale likes this.