Question about referring to specific game objects in scripts and booleans in Unity

Hi, I’m still pretty new to C# and still trying to understand using GetComponent(). I understand I can use GetComponent() like this when the script is attached to just one game object:

private Rigidbody rb;

    private void Start()
    {
        rb = GetComponent<Rigidbody>(); // rb = RigidBody component of object
    }

And can then make any changes to rb and have it reflected in the game. However, if I have one script attached to multiple game objects, but only want to affect one of them with a specific method or function, how would I do this? I’ve seen people use something like gameObject.GetComponent(), but I am not sure if “gameObject” is referring to the object name or something else like a tag (which would imply separate tags for everything that needs to be manipulated by itself), and how I would initialize this at the start of my script so it is accessible.

I also have another question that I’m curious about - say I have an image that I change the colour of in a script between black and white under certain conditions. Is there a way to use the current colour of the image in a boolean statement - for example, something like this:

    image.color = Color.white;
    if (image.color == Color.white)
    {
        image.color = Color.black;
    }

Or would I be better off just creating a string/int that corresponds to the image’s current colour and using this in the boolean statement instead? This obviously isn’t my intended usage, I’d just like a way to run some code within void Update() that changes the colour of an image, but I don’t want to attempt to overwrite the image colour if it is already the colour I want it to be.

A MonoBehaviour script is just another component attached to a GameObject in the scene. It has properties such as gameObject and transform to make this shorter to write (and slightly faster to use), but gameObject always refers to a GameObject the script is attached to. It’s just a reference in memory. No tags, no human-readable data.

You get your GameObject and are now able to access its API (and human-readable data such as name, for example). Similarly, by using transform property, you’re doing gameObject.GetComponent<Transform>() but it’s much faster than that, because GameObject must have a Transform component and it can be already found as GameObject.transform property. So using transform in the script is the same thing as using gameObject.transform, just shorter.

Previously, game objects were plagued by many such shortcut properties, like renderer and rigidBody.
Nowadays, Unity has cleaned this up, as evidenced by the following line in docs.

In general, unless you’re changing your game objects’ components in run time, you want to initialize other quick references for later use inside Awake. Awake is called only once, before Start, during the initialization phase of the object. At this point all other components should be known.

MeshRenderer _renderer;

void Awake() {
  _renderer = gameObject.GetComponent<MeshRenderer>();
}

void Update() {
  // do something with _renderer directly without having to 'get' it all the time, which has some work to do
}

You can just as well do this in Start, this is just a useful way to separate core technical initialization, from your logic state initialization. I tend to use Start, for example, to set my flags, initialize some animation values, that kind of thing, but your mileage may vary. Start is really just a special piece of Update, called immediately before the first Update is called (in other words, the user may “feel” perhaps some stutter, depending on the amount of work here, as soon as the object is activated (see SetActive), while Awake happens after the scene setup, which is potentially before any activation, so any work is stressed out in a less sensitive context).

Also consider this diagram as a useful guideline

the method below should work, but I am a noob myself.

public Rigidbody rb1;
public Rigidbody rb2;
public Rigidbody rb3;

private SameScript one;
private SameScript two;
private SameScript three;

private void somefunction()
{
one = rb1.GetComponent();
two = rb2.GetComponent();
three = rb3.GetComponent();
}