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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Prefab to activate Scene Object

Discussion in 'Scripting' started by TomsTales, Sep 7, 2021.

  1. TomsTales

    TomsTales

    Joined:
    Nov 3, 2020
    Posts:
    91
    Hi Guys,

    so I know I need to reference scene objects to prefabs that are spawned in (it's and item system). When "picking up" something, a buitton is activated. Pressing this new button (or item) should do something. Well, it doesn't. I have prepared a "simple" case:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Hate : MonoBehaviour
    6. {
    7.  
    8.     GameObject door;
    9.  
    10.     public void Start()
    11.     {
    12.         door = GameObject.FindGameObjectWithTag("Door");
    13.     }
    14.  
    15.    public void OpenDoor()
    16.     {
    17.         Debug.Log("Activated");
    18.         if(door != null)
    19.         {
    20.             door.SetActive(true);
    21.         }
    22.     }
    23. }
    I thought with finding the object with the "Door" tag I could activated it (the code does work when used with objects that are basic scene objects, just not with the prefab that is added later to the scene).

    Can someone help me how to reference to the object as I clearly am doing something wrong?

    Thanks!
     
  2. On-Stand-By

    On-Stand-By

    Joined:
    Sep 30, 2017
    Posts:
    14
    If the door is added later, getting it's reference in Start() is too early. Even if it's added in another Start(), it will depend on script execution order. (https://docs.unity3d.com/Manual/ExecutionOrder.html)
    To avoid this you can check if door have a reference before using it.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Hate : MonoBehaviour
    6. {
    7.     GameObject door;
    8.  
    9.     public void OpenDoor()
    10.     {
    11.         Debug.Log("Activated");
    12.         if (door != null)
    13.         {
    14.             door.SetActive(true);
    15.         }
    16.         else // Get door ref if there's none
    17.         {
    18.             door = GameObject.FindGameObjectWithTag("Door");
    19.         }
    20.     }
    21. }
    If there's going to be more than one door in your scene, you'll need another way to find your door as FindGameObjectWithTag() will return the first gameObject it finds.
     
  3. TomsTales

    TomsTales

    Joined:
    Nov 3, 2020
    Posts:
    91
    Hey mate, sorry I did not include this - the door is already in the scene, just not active. It's a button that is added with the "hate" (just because I already lost my mind lol) script on it!
     
  4. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,887
  5. TomsTales

    TomsTales

    Joined:
    Nov 3, 2020
    Posts:
    91
    Oh. That explains a lot.

    But I could have the object active but a certain script on it not and activate that script?

    let's just say the "Door" is a 2D Collider set to Trigger. There is a Script on it that sends the player to another position in the level. On the beginning of the scene, the "Door" is active, but the "Send" script component on it is not. I know spawn my prefab to the scene - this can now find the door and activate the "send"?

    Let's pretend there is no other, better and more efficient way, I am sure tehre are hundreds, but I try to understand and get it done now before trying to make it better :)