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

How do you access GameObject[] components?

Discussion in 'Scripting' started by plagugin, Feb 8, 2019.

  1. plagugin

    plagugin

    Joined:
    Dec 19, 2018
    Posts:
    4
    Hello people.

    I'm a novice and I'm having trouble finding solution to a problem. Working on my first game.

    In the part of my code shared bellow you can see I'm trying to pick up an object if the two criterias were met - that code itself works perfectly as long as only one object exists in the scene but when I duplicate the object to be able to pick up more items than just one in the game I am able to pickup only the latest duplicate.

    I know exactly where the problem is and it is in the variable declaration.

    As you can see later in the if statement - to be able to access the object's components I need to store the object in a variable which is currently done in Object = GameObject.FindWithTag("Item"); where i previously used just GameObject.Find which is bad also. GameObject.FindGameObjectsWithTag can't be used becasue of the same reason of not being able to access the components of the individual objects.
    And no, prefabs didn't work either.
    Or can it be somehow done?

    I will appreciate any help!



    Code (CSharp):
    1. private GameObject Object;
    2.    
    3.  
    4.    
    5.     void Start()
    6.     {
    7.  
    8.         Object = GameObject.FindWithTag("Item");
    9.  
    10.     }
    11.    
    12.     public void PickUp()
    13.     {
    14.     if (Input.GetButtonDown ("GamepadA") && Object.GetComponent<Interactable>().isInFov)
    15.         {
    16.             Debug.Log("Picked up - " + Object.GetComponent<Interactable>().item.name);
    17.             Inventory.instance.Add(Object.GetComponent<Interactable>().item);
    18.             Destroy(Object);
    19.         }
    20.  
    21.     }  
    22.  
    23.    
    24.    
    25.     void Update()
    26.     {
    27.         if (Object != null)
    28.         {
    29.         PickUp();
    30.         }
    31.     }
     
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Please don't call anything Object. That's just asking for weird name collisions.

    To access an item in an array, you simply call it by index. As in

    Code (CSharp):
    1. MyArayOfGameObjects[0].GetComponent<MyComponent>();
    You can also use for or foreach loops to access every item in an array.
     
  3. carl010010

    carl010010

    Joined:
    Jul 14, 2010
    Posts:
    139
    You'll need to modify the way you are getting your objects. Using GameObject.FindGameObjectsWithTag you can iterate through all of your gameobjects


    Code (CSharp):
    1. //Get an List of objects
    2. private List<GameObject> Objects;
    3.  
    4.     void Start()
    5.     {
    6.         //Get all objects in the scene by their tag
    7.         Objects = new List<GameObject>(GameObject.FindGameObjectsWithTag("Item"));
    8.     }
    9.  
    10.     public void PickUp()
    11.     {
    12.         //Iterate through the list of objects
    13.        for(int i = 0; i < Objects.count; i++)
    14.        {
    15.                 if (Input.GetButtonDown ("GamepadA") && Objects[i].GetComponent<Interactable>().isInFov)
    16.                 {
    17.                  Debug.Log("Picked up - " + Objects[i].GetComponent<Interactable>().item.name);
    18.                  Inventory.instance.Add(Objects[i].GetComponent<Interactable>().item);
    19.                  Objects.remove(Objects[i]);
    20.                  Destroy(Objects[i]);
    21.                  }
    22.        }
    23.     }
    24.  
    25.  
    26.     void Update()
    27.     {
    28.         if (Objects != null)
    29.         {
    30.         PickUp();
    31.         }
    32.     }
    Also while we are at it GetComponent is a very costly method. You don't want to call it every frame, but if you have too call it every frame you dont want to call it three times and should store it in a variable.

    Code (CSharp):
    1.  
    2. //Iterate through the list of objects
    3. for(int i = 0; i < Objects.length; i++)
    4. {
    5.     Interactable interactable = Objects[i].GetComponent<Interactable>();
    6.     if (Input.GetButtonDown ("GamepadA") && interactable.isInFov)
    7.         {
    8.             Debug.Log("Picked up - " + interactable.item.name);
    9.             Inventory.instance.Add(interactable.item);
    10.             Objects.remove(Objects[i]);
    11.             Destroy(Objects[i]);
    12.         }
    13. }
    14.  
     
  4. plagugin

    plagugin

    Joined:
    Dec 19, 2018
    Posts:
    4
    Thanks guys!