Search Unity

Question How to reference a Scene GameObject from a prefab?

Discussion in 'Scripting' started by octi123456, Mar 31, 2023.

  1. octi123456

    octi123456

    Joined:
    Mar 15, 2022
    Posts:
    5
    Hello, I'm having this issue in which I have a prefab player (Red square in prefabs folder) and I want to reference a GameObject (LostMenu) in the scene.

    upload_2023-3-31_10-52-36.png

    I read that there are some workarounds as Unity doesn't allow this, such as finding the GameObject through code.
    So, in the player's file I wrote:

    Code (CSharp):
    1. private LostMenu lostMenu;
    2.  
    3. void Start() {
    4.         lostMenu = GameObject.Find("LostMenu").GetComponent<LostMenu>();
    5.         Debug.Log(lostMenu);
    6. }
    The problem is the script can't find the GameObject even though it exists, when I debug the objects, it just throws nullpointerexception (the element is clearly present in the scene as the picture shows). I don't know if this has something to do with the fact that the prefab is not in the scene.
     

    Attached Files:

  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    GameObject.Find doesn't find inactive objects.

    So, you have to do other options.
    1. Don't use GameObject.Find. Instead, have LostMenu have a static reference to itself. (similar to a singleton, but you might not need it to float around scenes)
    2. Have LostMenu script on an active object.
    3. Use one of the other find methods that does support inactive objects.
    4. Have your script that instantiates the player have a ref to LostMenu that it can pass to your Player object and set up the reference instead of trying to in Start on the Player.
    5. Probably other ways as well..
     
    octi123456 and Chubzdoomer like this.
  3. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Your "LostMenu" game object is inactive in the scene, and the default behavior of Find is to ignore inactives.

    It is far better and easier to use FindObjectOfType instead of Find
    Code (CSharp):
    1. //the boolean is to indicate whether to include inactives in the search or not
    2. lostMenu = GameObject.FindObjectOfType<LostMenu>(true);
     
    octi123456 and Chubzdoomer like this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,752
    StarManta and octi123456 like this.
  5. octi123456

    octi123456

    Joined:
    Mar 15, 2022
    Posts:
    5
    Thank you very much!
    I used
    Code (CSharp):
    1. lostMenu = Resources.FindObjectsOfTypeAll<LostMenu>()[0]
    as I only have one LostMenu instance and it instantly worked!
     
  6. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    The more common solution is to assign the reference when spawning the prefab:
    Code (CSharp):
    1. Menu menu1=Intantiate(menuPrefab);
    2. menu1.lostObject=[my inspector-assigned menu-link]