Search Unity

Reference in Prefab colliding returns null

Discussion in 'Scripting' started by rasmusnielsen, Feb 21, 2020.

  1. rasmusnielsen

    rasmusnielsen

    Joined:
    Feb 7, 2020
    Posts:
    11
    Hi awesome people.

    I'm a little stuck and would like some feedback! The concept is as follows:
    Every x seconds I instantiate a prefab. If player collides with this - they die.

    I have a main script with a method called PlayerDied() where I track score and alot of other stuff. I would love to have it centralized here.

    Main.cs
    Code (CSharp):
    1. public void PlayerDied() {
    2.     //SceneManager.LoadScene("GameOver");
    3.     print("Auch");
    4. }
    So, On my prefab I have a script attached, where I want to reference THAT method. It look like this.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class BadFood : MonoBehaviour
    6. {
    7.     public Main other;
    8.  
    9.      private void Start()
    10.      {}
    11.  
    12. public void OnTriggerEnter2D(Collider2D target)
    13. {
    14.  
    15.      if(target.tag == "Hit")
    16.      {  
    17.         other.PlayerDied();  
    18.      }
    19. }
    20. }
    BUT, When collision happens I get the following error.

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. BadFood.OnTriggerEnter2D (UnityEngine.Collider2D target) (at Assets/Scripts/BadFood.cs:31)
    How do I proceed?
     
    Last edited: Feb 21, 2020
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    You should always try to indicate the exact line where the error occurred. The error message says it was on line 31, but your posted code only goes up to line 20 (probably because you removed some stuff that wasn't important, which is fine, but then you need to clarify which line is affected).

    My silver-bullet guess is that it's occurring on line 17 or your posted code--where it says "other.PlayerDied()"--which would mean that the variable "other" is null. Probably because you forgot to drag a value into it in the inspector, or otherwise forgot to initialize it to a valid value.
     
    rasmusnielsen likes this.
  3. rasmusnielsen

    rasmusnielsen

    Joined:
    Feb 7, 2020
    Posts:
    11
    Thanks for the answer so far, and YES. The error occurs with the "other.PlayerDied()". Just a quick question, what do I drag in to the slot? The GameObject which the script is attached to, or the actual script? Neither seems to work. Please see .gif below!
     

    Attached Files:

    • Hm.gif
      Hm.gif
      File size:
      2.4 MB
      Views:
      329
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    When you write "other.PlayerDied()", that means you want to call the PlayerDied() function on whatever object is stored in the "other" variable. So the thing you should drag in there is whatever object you want to execute PlayerDied().

    Since you set the type of the variable as "Main", Unity will only let you drag something of type "Main" into the slot.

    Also note that prefabs can't include references to anything in a scene (because from Unity's perspective, there's no guarantee that scene will be loaded when you instantiate the prefab). So if this is a prefab, you'll either need to set the reference at runtime after you instantiate it, or you'll need to switch to copying an object that exists in the scene instead.
     
    rasmusnielsen likes this.
  5. rasmusnielsen

    rasmusnielsen

    Joined:
    Feb 7, 2020
    Posts:
    11
    Ah, that actually kinda makes sense now. At least the concept around it - and yes it is a prefab. I like the idea of setting the reference at runtime. Can you help me a little further with a specific snippet that will do this? Again. Thank you!
     
    Last edited: Feb 22, 2020
  6. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    If whatever script spawns the BadFood has a reference to Main, it can set the variable after instantiation; e.g.

    Code (CSharp):
    1. BadFood badFoodBeingSpawned = Instantiate<BadFood>(badFoodPrefab);
    2. badFoodBeingSpawned.other = someVariable;
    If "Main" is itself the thing doing the spawning, it can refer to itself using the keyword "this".

    If you can't figure out a place to put a variable, you could potentially use some version of Find to get access to your Main. (Just make sure you're not doing this every frame, because it's a little expensive.)