How to enable components after disabling them through script?

I’m trying to replicate the main mechanic of Hue, which, if you haven’t played it, let me give you a brief explanation on how it works. Hue is a game where you control colors. You have a pallet of colors which can be used to change the background’s color. On every stage there’s a puzzle you have to solve. There are some objects that are the same colors as the pallet. If you set the background’s color to the same as the obstacle, that obstacle will disappear and if you change to a different color the obstacle will reappear. See image for reference.alt text

I have made a function that changes the background’s color depending on what button you pressed.

public void ChangeColor() 
    {
        string ButtonPressed = EventSystem.current.currentSelectedGameObject.name;
        GameObject button = GameObject.Find(ButtonPressed);
        camera.backgroundColor = button.GetComponent<Image>().color;
    }

And another one that disables the obstacle’s Rigibody and BoxCollider depending on what color was chosen.

     public void BoxDetection(string color)
    {
        GameObject[] boxes = GameObject.FindGameObjectsWithTag(color);
        foreach (GameObject box in boxes)
        {
            box.GetComponent<Rigidbody2D>().isKinematic = true;
            box.GetComponent<BoxCollider2D>().enabled = false;
        }
    }

All of this works perfectly fine but my problem is, how do I reactivate the components after the background is changed yet again? Let’s say I have a purple box, I change the background to purple and that box “disappears”. Now I change the background to green, the purple box will be visible but not interactable. How can I reactivate the components in this situation?

I’d use an enum property to track the colors of boxes (call it “ObjectColor” or something). Make a script to use for these boxes, call it “BoxStats”, or “Object Stats”, or whatever pleases you, and make the enum there. Instead of looking for only boxes of the selected color, cycle through all objects of type “BoxStats” (looks for objects with that script).

For every box that == the selected background color, disable rb and colliders, and do the opposite for all boxes != to the background color.

Here’s some sudo-ish code. I’ve also added a slight optimization; it’ll make it so you only have to call “GetComponent” once per box since you’ll have direct access to the components via the script.

Maybe have your box/object class be something simple for holding values and references like this:

public class ColorObject: MonoBehaviour
{

   // define enum
    public enum ObjectColor { Red, Green, Blue}

  //declare a variable with your enum type
  //make sure it's public so you can set color in inspector
    public ObjectColor objectColor;

     //you can also cache references to components in your stats script to save having to
     //... GetComponent several times per box, this will save on performance.
    public Rigidbody2D rb2D;
    public BoxCollider2D boxCollider2D;


}

And then modify your current search script just a little to search for the objects with the class type…

public void BoxDetection(string color)
     {
         ColorObject[] boxes = GameObject.FindObjectsOfType<ColorObject>();
         foreach (ColorObject box in boxes)
         {
             //compare name of enum to color string, if same color then disable
             if(box.objectColor.ToString() == color)
             {
                  //you can eliminate the need to do several GetComponent calls by
                 //... saving references to the ColorObject script, this will save performance cost...
                 //... since get component is quite expensive.
                  box.rb2D.isKinematic = true;                  
                  box.boxCollider2D.enabled = false;
              }
             else
            {
                  //if these boxes are a different color then enable stuff
                  box.rb2D.isKinematic = flase;                  
                  box.boxCollider2D.enabled = true;
            }
             
         }
     }

Well, if you have exactly those 8 colors (or other colors but the color count is below say 16) you could simply use collision layers. You give every color a certain layer. When changing the color you also change the layer of the object. Since you want objects with the same color to not collider but all other should collide, you just have to set this up in the collision matrix.

The exact mechanic is not really clear, I never played the game you mentioned. However I would highly recommend that you abstract the “color” away by using a global Color array where you define all your colors. When you want to change the color you would refer to the color by the index. Using single numbers makes your life much simpler in the long run.