0

I want to change the Material, and disable the box collider of multiple objects with the same tag on pressing one key, or receiving a single input, let's say this happens on clicking the "w" key on the keyboard.

My original idea was to loop through all objects with the tag and disable it and change the material. But I just can't do it. (I'm new to C#)

1 Answers1

0

You should use the FindGameObjectsWithTag() as little as possible or not use at all (cause it is very expensive) instead if finding GameObjects at runtime is not needed use a data structure like a List to save all the GameObjects beforehand .

If you need to find the GameObjects at runtime . .

  • First check for your desired input inside the Update() method
  • Then inside that you can get all the GameObjects with the same tag by using the FindGameObjectWithTag() callback and save it into an array
  • After that we can loop through the array and get the collider and renderer attached with it
  • Lastly we disable the collider and material of the renderer
  • We should use a bool so our input should not get counted before all the collider and material got changed

Here is the code for that . .

public class TestFind : MonoBehaviour
{
    public Material newMaterial;
    
    private bool _haveAllObjectsFound = false;
    
    private void Update()
    {
        // check if the W key is pressed and we haven't found all the objects yet
        if (Input.GetKeyDown(KeyCode.W) && !_haveAllObjectsFound)
        {
            // gets all the game object with the tag "MyTag"
            GameObject[] allFoundObjects = GameObject.FindGameObjectsWithTag("MyTag");
            _haveAllObjectsFound = true;

            // loop through all the found objects to disable their colliders and change their materials
            foreach (var foundObject in allFoundObjects)
            {
                BoxCollider foundCollider = foundObject.GetComponent<BoxCollider>();
                Renderer foundRenderer = foundObject.GetComponent<Renderer>();
                
                foundCollider.enabled = false;
                foundRenderer.material = newMaterial;
            }
            
            _haveAllObjectsFound = false;
        }
    }
}

If you don't need to find the GameObjects at runtime..

  • Use a List<GameObject> to store and set the GameObjects to the list in the Editor/Inspector
  • Now directly loop through the List instead of finding and getting the GameObjects via tag

Here is the code for that . .

public class TestFind : MonoBehaviour
{
    public List<GameObject> allFoundObjects = new List<GameObject>();
    public Material newMaterial;
    
    private bool _haveAllObjectsFound = false;
    
    private void Update()
    {
        // check if the W key is pressed and we haven't found all the objects yet
        if (Input.GetKeyDown(KeyCode.W) && !_haveAllObjectsFound)
        {
            _haveAllObjectsFound = true;

            // loop through all the found objects to disable their colliders and change their materials
            foreach (var foundObject in allFoundObjects)
            {
                BoxCollider foundCollider = foundObject.GetComponent<BoxCollider>();
                Renderer foundRenderer = foundObject.GetComponent<Renderer>();
                
                foundCollider.enabled = false;
                foundRenderer.material = newMaterial;
            }
            
            _haveAllObjectsFound = false;
        }
    }
}
sujoybyte
  • 584
  • 4
  • 19