Is A vs. Has A

A general question about Unity. I’m a bit surprised that you get a handle to a GameObject by:

  foreach (Pin pin in GameObject.FindObjectsOfType<Pin>()) {

Mostly as there is no “pin” object; there is a pin script however. Not only that, even if you did get the script directly, it seems to know that there is a rigidbody attached, or we wouldn’t have the transforms.

Not only that, I have Gnomes instead of pins, and I figured I’d have to change this line of code. The pin is a script component to the GameObject “Gnome”.

The code ran fine as is.

So, if I had two different objects, one is “Pin” and the other is “Gnome” but both “has a” script called Pin, FindObjectsOfType works for either?

Seems odd.

To further add confusion, in the shredder we have:
GameObject thingLeft = collider.gameObject;

	if (thingLeft.GetComponent<Pin> ()){
		Destroy (thingLeft);

which seems to be more of a “HasA” which is what I’d expect.

== John ==

P.S. This is why I take these courses, I would have been stumped for days over this one :slight_smile:

The pin is a type of object not a physical object. Its like saying that a MacIntosh is a type of apple.

foreach (Pin pin in GameObject.FindObjectsOfType()) {

In this line you are saying for every type of object “pin” in the array of objects of type { Do something }.

I hope that makes sense and I didn’t confuse you more. It’s a nice way of referencing objects of a certain type.

It all stems from how types and objects works in an OOP environment and inheritance.

When you create a script, you’re creating a new class (sometimes a struct) of objects. For example:

with this line you’re creating a new class, named MyClass, which is child of SuperClass (the class from which you inherit is called a Super or Parent).
The new class defines a new type, with the same name as the class itself.

So, if the question is “why, when I access an instance of an object of type T, I can access the proprieties like transform etc.?”, it all comes down to the class from which the class of type T inherits, which in our case is almost always the MonoBehaviour one (which in turns inherits from Behaviour, in turn inheriting from Component, etc.), since an object of class T has access to the proprieties of all the classes from which it inherits.

In your example, you have a class named Pin, which defines the type Pin. The inheritance hierarchy of this class is:

Pin : MonoBehaviour : Behaviour : Component : Object

thus an instance of type Pin will have all the proprieties of the classes MonoBehaviour, Behaviour, Component and Object. For example, transform and gameObject are fields of the class (type) Component, so you’ll be able to access them.

You’ll probably know that there’s a method called SetActive, which allows you to enable/disable game objects at runtime. Ever wondered, however, why this method is NOT available for components? Because it’s a method defined in the class GameObject, which inherits only from the class Object, so you can’t disable a component since the Component class inherits directly from Object, but not from GameObject. In order to do this (disable a component of a game object), you’ll need to use the field .enabled, which is defined inside the class Behaviour and thus available to all classes children of Behaviour (and the Behaviour class itself, ofc).

Hope this makes some sense.

2 Likes

Privacy & Terms