How does GameObject have a gameObject member?

It doesn’t inherit from Component, but gameObject.gameObject==gameObect returns true.

Edit : to clarify: I’m wondering where this ‘gameObject’ member comes from, as a matter of idle curiosity mostly rather than an issue of pressing concern, rather why it behaves the way it does.

1 Like

Do you understand what “this” mean in an OO language?

Yes. In method bodies it’s usually a reference to the instance whose method is being called. Why do you ask?

Because basically what you wrote is this.this == this

By what mechanism does “gameObject” translate into “this”? Am I ignorant of some language feature here? I’m mightily confused now…

( to clarify, I’m wondering where the ‘gameObject’ member of GameObject comes from )

“gameObject” returns the current game object the script is attached to. All GameObject objects also have a “gameObject” property (this is possibly from it being inherited from a base class, or perhaps a legacy issue) which ends up referring to itself (it IS the game object)

“this” helps you reference a property on the current script. All scripts have a “gameObject” property. If you do not use “this”, it is implied by whatever you type. So:

“this.gameObject” is the equivalent to just typing “gameObject”.

Since GameObjects contain a gameObject property, which points to itself, you can keep referencing it: this.gameObject.gameObject.gameObject.gameObject.gameObject and so on.

So finally, typing:

gameObject == gameObject

is the same as

this.gameObject == this.gameObject

therefore:

this.gameObject == gameObject

and since GameObject’s have a gameObject property that points to itself:

this.gameObject.gameObject == gameObject

If, what you are saying is true that gameObject.gameObject==gameObject = true then the Unity reference does not specify that gameObject is a variable of GameObject, but it is. If it is not, then gameObject is not a variable of GameObject.

“this” refers to the calling member. It inherits the variables and functions of GameObject. Since, scripts cannot be attached to anything but GameObjects, this will ALWAYS refer to the game object.

There’s only one other base class, Object, that doesn’t have a gameObject member, so I guess I’ll chalk it up to being a weird undocumented anomaly/legacy thing then.

(and yep - I understand its behaviour - the code example I gave in the first post was misleading, I should just have asked about the existence of the gameObject member rather than give that silly equality)

1 Like

“gameObject” does exist as a variable (rather a getter, there’s no setter) on GameObject. Yeah, it’s undocumented (not in the Script Reference) but it’s clearly in the .NET dll’s:

#region Assembly UnityEngine-Debug.dll, v2.0.50727
// C:/Program Files/Unity/Editor/Data/lib/UnityEngine-Debug.dll
#endregion

using System;

namespace UnityEngine
{
    public class GameObject : Object
    {
        public GameObject();
        public GameObject(string name);
        public GameObject(string name, params Type[ ] components);

        public bool active { get; set; }
        public Animation animation { get; }
        public AudioSource audio { get; }
        public Camera camera { get; }
        public Collider collider { get; }
        public ConstantForce constantForce { get; }
        public GameObject gameObject { get; }
        [Obsolete("Please use guiTexture instead")]
        public GUIElement guiElement { get; }
        public GUIText guiText { get; }
        public GUITexture guiTexture { get; }
        public HingeJoint hingeJoint { get; }
        public int layer { get; set; }
        public Light light { get; }
        public NetworkView networkView { get; }
        public ParticleEmitter particleEmitter { get; }
        public Renderer renderer { get; }
        public Rigidbody rigidbody { get; }
        public string tag { get; set; }
        public Transform transform { get; }

        public T AddComponent<T>() where T : Component;
        public Component AddComponent(string className);
        public Component AddComponent(Type componentType);
        public void BroadcastMessage(string methodName);
        public void BroadcastMessage(string methodName, object parameter);
        public void BroadcastMessage(string methodName, SendMessageOptions options);
        public void BroadcastMessage(string methodName, object parameter, SendMessageOptions options);
        public bool CompareTag(string tag);
        public static GameObject CreatePrimitive(PrimitiveType type);
        public static GameObject Find(string name);
        public static GameObject[ ] FindGameObjectsWithTag(string tag);
        public static GameObject FindGameObjectWithTag(string tag);
        public static GameObject FindWithTag(string tag);
        public T GetComponent<T>() where T : Component;
        public Component GetComponent(string type);
        public Component GetComponent(Type type);
        public T GetComponentInChildren<T>() where T : Component;
        public Component GetComponentInChildren(Type type);
        public T[ ] GetComponents<T>() where T : Component;
        public Component[ ] GetComponents(Type type);
        public T[ ] GetComponentsInChildren<T>() where T : Component;
        public T[ ] GetComponentsInChildren<T>(bool includeInactive) where T : Component;
        public Component[ ] GetComponentsInChildren(Type type);
        public Component[ ] GetComponentsInChildren(Type type, bool includeInactive);
        [Obsolete("gameObject.PlayAnimation is not supported anymore. Use animation.Play")]
        public void PlayAnimation(AnimationClip animation);
        public void SampleAnimation(AnimationClip animation, float time);
        public void SendMessage(string methodName);
        public void SendMessage(string methodName, object value);
        public void SendMessage(string methodName, SendMessageOptions options);
        public void SendMessage(string methodName, object value, SendMessageOptions options);
        public void SendMessageUpwards(string methodName);
        public void SendMessageUpwards(string methodName, object value);
        public void SendMessageUpwards(string methodName, SendMessageOptions options);
        public void SendMessageUpwards(string methodName, object value, SendMessageOptions options);
        public void SetActiveRecursively(bool state);
        [Obsolete("gameObject.StopAnimation is not supported anymore. Use animation.Stop")]
        public void StopAnimation();
    }
}

It serves little purpose. The only foreseeable use I can conceive of (beyond possibly some internal Unity processing), would be using reflection to access the “gameObject” member on different objects interchangeably (components/scripts, game objects, etc.) But even then, that’s a pretty odd (and likely unneccessary) usage of reflection.

1 Like

gameObject is shorthand of writing this.gameObject.
What context are you writing this in? And gameObject is not a method…

Yes I know I know I promise I know.

The context is one of curiosity and anxiety.

Typo on my part.

Anyway, thanks for the replies, and apologies for the bad wording of the OP, I think I can say that I’ve achieved closure now on this issue :slight_smile:

1 Like

In visual studio, you can right click and find every use of it. For fans of micro-optimizations, you can remove the redundant code.

It’s probably a weird legacy thing from the Boo and UnityScript days.

9588994--1358476--upload_2024-1-18_9-43-30.png

Please don’t necropost.