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 "Object reference not set" bug that I can't fix?

Discussion in 'Scripting' started by androidac67, Aug 2, 2023.

  1. androidac67

    androidac67

    Joined:
    Jan 3, 2023
    Posts:
    75
    I'm not sure if it's actually a bug but everything works fine minus the error. I have a script attached to my player which has this code:

    Code (CSharp):
    1. // Trigger script
    2. public Transform mainObject;
    3.  
    4. public void OnTriggerEnter(Collider other)
    5.     {
    6.         if (!other.CompareTag("EnterTrigger")) return;
    7.  
    8.         canEnter = true;
    9.         mainObject = other.transform.parent; // this turns null inside OnTriggerExit
    10.  
    11.     }
    So basically I created it so that any object in my scene with the tag "EnterTrigger" will simply replace the current "mainObject" that is in my inspector under the public Transform.

    The only thing I can add is that in my update, I do have an if statement which references the MainObject transform which is where the error is coming from, so I guess once I exit trigger, the game no longer detects that transform so it gives me the error.

    My issue is that once I leave the trigger, the transform is no longer set so I get
    None (transform)
    in my inspector, and then my console gets spammed a few times with "Object reference not set to an instance of an object". I know why it is happening, but the game doesn't break or anything. If I re-enter the trigger, everything is fine and the object gets reassigned in the inspector and there's no issues.

    Is there a way to prevent that error from popping up or do I need to adjust my code?
     
    Last edited: Aug 2, 2023
  2. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    I'm not sure if you can check a tag on just a collider, so I think you need
    if (!other.gameObject.CompareTag())


    but one way to debug this to make sure it works, is just add a print function:
    Code (CSharp):
    1. public void OnTriggerEnter(Collider other)
    2.     {
    3.         if (!other.CompareTag("EnterTrigger")) return;
    4.         print($"current OnTriggerEnter = {other.name}");
    5.         canEnter = true;
    6.         mainObject = other.transform.parent; // this turns null inside OnTriggerExit
    7.     }
     
  3. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         if (mainObject!=null)
    4.         {
    5.             // do something wonderful with mainObject
    6.         }
    7.     }
     
  4. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    Code (CSharp):
    1. mainObject = other.transform.parent; // this turns null inside OnTriggerExit
    I'm not following what you're saying here. If it's not null here i.e. there IS a parent Transform but in some code you don't show (OnTriggerExit) then "mainObject" is null, well then that's because that object has been deleted or you've set the field to NULL somewhere. Obviously you'll get an Exit BECAUSE it's been deleted as the collider will be deleted too.

    When you leave the trigger, "mainObject" will still be referring to that object if it still exists. The physics engine nor anything else in Unity will change it. You're deleting the object or setting it to null somewhere. In the end, it's a field referencing a Unity object, that's all.

    If none of this is true then maybe you should try to be clearer on what the problem is, what code is doing what and when it happens (show where you get this from).

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

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    Wow.. I'll be a monkey's uncle... That means I've been going out of my way for ages, also referencing the gameObject in collision checks.. oof

    But yeah, I was trying to get him used to using print(), as it really does save the day with almost any error.
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    Well technically you're correct because that state (and other stuff) is indeed stored on the GameObject but because of the synergy between GameObject and Components, certain properties and methods are added to the Component which just implicitly call the GameObject it's attached to.

    GetComponent(s), name, transform, CompareTag etc. All here: https://docs.unity3d.com/ScriptReference/Component.html
     
  8. androidac67

    androidac67

    Joined:
    Jan 3, 2023
    Posts:
    75
    Sorry I thought I solved the issue but it looks like I didn't. The error is coming from this line in my camera script inside the Update method(its the trigger.MainObject.rotation):

    var xQuat = Quaternion.RotateTowards(trigger.MainObject.rotation, Quaternion.AngleAxis(rotation.x, Vector3.up), xRotationLimit);


    That code is to clamp my x-axis rotation to prevent gimbal lock and when I interact with the trigger, my player rotates towards the object, so everything works on that end.

    So for example I have 10 door objects (they all have the same tag) and in my inspector I have one of those doors assigned as the 'MainObject'. So when I enter the trigger of any of these 10 door objects that all share the same tag, they all perform the same function from the same "trigger" script which is good. However the issue is that when I exit the trigger of any of these 10 doors, the transform in the inspector automatically changes to
    None (transform)
    . But if I enter the trigger again of any of these 10 objects, the transform gets updated to 'MainObject' again. And that repeats every time I exit/enter trigger. And even though there is technically no issues, glitches, bugs, etc, occuring during gameplay, my console gets spammed with a few of those errors each time I exit trigger which is annoying to look at.
     
  9. androidac67

    androidac67

    Joined:
    Jan 3, 2023
    Posts:
    75
    Yeah I tried this and also looked at the link MelvMay sent and adjusted my code according to those 3 results but the issue still persists
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    You do have a bug, this isn't a Unity bug. It's impossible for anyone here to debug this for you. In the end, if you're accessing a field and it's set to NULL, you'll get the exception because you obviously cannot access NULL.

    Then, as I said, you're resetting that field to NULL or are deleting the object it's referencing. There is nothing else and this should be easy to find if you can reproduce it. After all, this will be your code doing this. :)

    I'm actually not sure what else can be said without access to the project but most devs here won't debug your project for you TBH.
     
  11. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    As soon as Melv said no one can debug this, I heard challenge, and immediately think challenge accepted o_O

    So if you have a trigger method, that is supposed to accept a collider in said trigger, that should be for trigger and collider alone. Now you obviously playing around with Inheritance(kudos btw), so by calling parent, without fully understanding how Inheritance works, you are now giving a singular command to multiple objects. This is not good..

    unless you're making a function, like in Rust where the keypad can open or close all doors, then hey congratulations for not needing a "for loop" to do said function.

    But in any code, a declaration of a "main" whether object or class, should be a singular instance. So true, to fully give you a more correct and to the point answer, we would need to see the code. But I'm pretty sure, however you have your Inheritance setup, is in itself wrong.

    You show a trigger script, which personally I think this action should just be in whatever requires said collision(trigger v collider), and not as a copy/paste separate class. This is just my opinion.

    So by trying to fix this, as a simple print debug, you're probably not going to get desired messages to handle your conflict. As
    mainObject = other.transform.parent;
    is probably returning way more objects, since the use of
    other.transform.parent;
    is now calling every child from said parent. So this is the main question, who is the parent?

    As I normally have to deal with this, if having parent of an empty gameObject with the class, but the Collider might actually be in one of the children. One out-of-the-way fix for this, is what ever has the collider needs it's own class, and any collisions with it, should be communicating with cached variables from child-to-parent communication. As calling transform.root or transform.parent can give different results than you expect.

    So hopefully something I said, gave you an idea of what may be wrong, and helps you solve it on your own. But if you still can't find the root of the problem, please insert all related functions, or classes as code snippets in your post(there should be an Edit button), hopefully while not overloading us with 7 full classes of 200 lines, lol. But just let us know when you're done re-asking your question :)
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,468
    In the sense that devs can play the guessing game but not debug. :)
     
    wideeyenow_unity likes this.