Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

How to disable and enable gameObjects of an array

Discussion in 'Scripting' started by gkraken333, Nov 6, 2019.

  1. gkraken333

    gkraken333

    Joined:
    Sep 16, 2019
    Posts:
    7
    hello, I am currently working on an rpg, in it I have a quest manager where I have an array of quest objects that have start and end mission triggers, the problem is that these triggers are activated even when the previous mission has not been completed, I need to know how I can disable array objects and enable them as they are completed (start with an array of 0 to 2, where quest object 0 is enabled and 1 and 2 are disabled, once 0 is completed, 1 is enabled, once 1 is completed, 2 is enabled)

    This is the questManager code:
    Code (CSharp):
    1.  
    2. public QuestObject[] quests;
    3.     public bool[] questsCompleted;
    4.     public DialogManager DM;
    5.     public string itemCollected;
    6.     // Start is called before the first frame update
    7.     void Start()
    8.     {
    9.         questsCompleted = new bool[quests.Length];
    10.     }
    11.     // Update is called once per frame
    12.     void Update()
    13.     {
    14.     }
    15.     public void ShowQuestText(string questText)
    16.     {
    17.         DM.dialogLines = new string[1];
    18.         DM.dialogLines[0] = questText;
    19.         DM.currentLine = 0;
    20.         DM.ShowDialogue();
    21.     }
    22.  
    This is the QuestObject code:
    Code (CSharp):
    1.  public int questNumber;
    2.     public QuestManager QM;
    3.     public string startText;
    4.     public string endText;
    5.     public bool isItemQuest;
    6.     public string targetItem;
    7.  
    8.     // Start is called before the first frame update
    9.     void Start()
    10.     {
    11.        
    12.     }
    13.  
    14.     // Update is called once per frame
    15.     void Update()
    16.     {
    17.         if(isItemQuest)
    18.         {
    19.             if (QM.itemCollected == targetItem)
    20.             {
    21.                 QM.itemCollected = null;
    22.                 EndQuest();
    23.             }
    24.         }
    25.     }
    26.  
    27.     public void StartQuest()
    28.     {
    29.         QM.ShowQuestText(startText);
    30.     }
    31.  
    32.     public void EndQuest()
    33.     {
    34.         QM.questsCompleted[questNumber] = true;
    35.         gameObject.SetActive(false);
    36.         QM.ShowQuestText(endText);
    37.     }
    And this is the triggers code:
    Code (CSharp):
    1.  private QuestManager QM;
    2.     public int questNumber;
    3.     public bool startQuest;
    4.     public bool endQuest;
    5.  
    6.     // Start is called before the first frame update
    7.     void Start()
    8.     {
    9.         QM = FindObjectOfType<QuestManager>();
    10.     }
    11.  
    12.     // Update is called once per frame
    13.     void Update()
    14.     {
    15.        
    16.     }
    17.  
    18.     private void OnTriggerEnter2D(Collider2D collision)
    19.     {
    20.         if(collision.gameObject.name == "Player")
    21.         {
    22.             if(!QM.questsCompleted[questNumber])
    23.             {
    24.                 if(startQuest && QM.quests[questNumber].gameObject.activeSelf)
    25.                 {
    26.                     QM.quests[questNumber].gameObject.SetActive(true);
    27.                     QM.quests[questNumber].StartQuest();
    28.                 }
    29.  
    30.                 if(endQuest && QM.quests[questNumber].gameObject.activeSelf)
    31.                 {
    32.                     QM.quests[questNumber].EndQuest();
    33.                 }
    34.             }
    35.         }
    36.     }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,369
    The reference way to do this in Unity is to list them all in a master controlling list, then on Awake iterate that list and set them all to .SetActive(false).

    Now you can activate one at a time, turning all the others off.

    Things to watch out for: in the quest scripts, don't do anything in Awake() or OnEnable() that you don't mind happening when a quest might be off. In other words, use Start() so that the script is disabled before its Start() gets called.

    This can help you visualize the timing on the Awake, OnEnable, Start, etc. methods:

    https://docs.unity3d.com/Manual/ExecutionOrder.html

    And you can make a simple index select only one item to turn on with a construct like this:

    Code (csharp):
    1. int which = (put whatever number you want into which);
    2.  
    3. for (int i = 0; i < Quests.Length; i++)
    4. {
    5.   // only the one matching i == which will be on, all others will be off
    6.   Quests[i].SetActive( i == which);
    7. }
    Where Quests is your GameObject[] array.
     
  3. gkraken333

    gkraken333

    Joined:
    Sep 16, 2019
    Posts:
    7
    You absolute save me, thanks a lot for the reply!
     
    lyingturkey and Kurt-Dekker like this.
  4. thecapitankaty

    thecapitankaty

    Joined:
    Nov 21, 2020
    Posts:
    12
    how would i be able to invert this AKA instead of making them turn on have them turn off
     
  5. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,687
    Swap the comparison symbol to the inverse:
    !=
    .
     
  6. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,214
    You can also think of this
    Code (csharp):
    1. int which = (put whatever number you want into which);
    2.  
    3. for (int i = 0; i < Quests.Length; i++)
    4. {
    5.   // only the one matching i == which will be on, all others will be off
    6.   Quests[i].SetActive( i == which);
    7. }
    like this
    Code (csharp):
    1. deactivateAllQuests();
    2. activateQuest(3);
    (Edit: it's not exactly the same thing, but the difference is negligible.)
    where
    Code (csharp):
    1. void deactivateAllQuests() {
    2.   for(int i = 0; i < Quests.Length; i++)
    3.     Quests[i].SetActive(false);
    4. }
    5.  
    6. void activateQuest(int index) {
    7.   Quests[index].SetActive(true);
    8. }
    Hopefully you can now improvise yourself.
    For example
    Code (csharp):
    1. activateAllQuests();
    2. deactivateQuest(3);
     
    Ryiah likes this.