Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Unity classes relationship .

Discussion in 'Scripting' started by psykick1, Jun 19, 2020.

  1. psykick1

    psykick1

    Joined:
    May 19, 2020
    Posts:
    61
    Hi everyone,

    Reading about classes relationship in unity website and found the following hirerchy:

    all the component attached to the gameobject is a child of class "Component"
    "Component" + "GameObject" is a child of base class "Object"

    As I know in c# , Child class can access a parent class but not the reverse.

    Ok.. so what is the question?
    Following to unity documentation, when Instatiation a GameObject,
    We actually Instantiating the parent class called "Object".
    How does all the other childerns object instantiating automaticlly with the parent?
    and actually how they're attached to the parent? ..
    for example. after Instantiation a object we can say.
    theRefOfGameObject.GetComponent , but actually GetComponent is a method in GameObject class not in
    Object Class..

    What am I missing?
    Thanks.
     

    Attached Files:

  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,971
    Unity uses a "component model."

    GameObjects are the basic building block of your scenes.

    Components are plugged into GameObjects.

    EVERY GameObject has at least one Component, either a Transform or a RectTransform. This Transform controls position, scale and rotation, as well as parenting a GameObject to others (or not).

    GameObjects might have more Components too, such as your scripts (MonoBehaviours) or a Camera or Light, or Collider, or really anything that is a Component.

    Assets are broadly things that exist on disk. You assign references to assets into fields in Components.

    You can also put references to other Components into Components.

    Aliases to .GetComponent and its kin are exposed in various places, such as GameObject and Component.
     
  3. psykick1

    psykick1

    Joined:
    May 19, 2020
    Posts:
    61
  4. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,926
    Unity has has 3 different meanings for "child". It can be difficult to figure out which means what. Plus, most explanations of inheritance aren't very good. A better way to understand inheritance might be to use Unity in a practical way, then read the theory.

    When a class inherits from another, it's completely self-contained. So sure, GameObject inherits from Object, but you will never see the Object part dangling from it. When you type GameObject g1; and scroll through the options in g1-dot, a few of those things are inherited from Object. That's the only place Object comes in.

    Likewise Rigidbody inherits from Component. But when you use Component->New->Rigidbody, you get a Rigidbody and nothing else. The Component part is completely built-into it. The only way you know is that it has GetComponent() function and can be in a gameObject's component list.

    To clarify what Kurt-D wrote, Unity confuses things a little by automatically adding a Transform to every gameObject. That's not inheritance or any other rule. It's just how Unity decided it wants to work. GameObjects have a whole list of Components, but only because Unity said they did. That's nothing to do with inheritance.

    Knowing "inherits from Component" can help when you see new classes. For example, UnityEvent doesn't inherit from Component. That means you don't add it to a gameObject (or a better clue: the AddComponent dropdown doesn't have UnityEvent).
     
    Kurt-Dekker likes this.
  5. psykick1

    psykick1

    Joined:
    May 19, 2020
    Posts:
    61
    following to unity documentation, There is 2 GetComponent method.
    1 Inside GameObject class
    2. Inside Component class

    What I wondering long time and really cannot find the answer, is actually what happends inside the GameObject Class.


    All the components instantiating there?
    lets say for example:
    RigidBody rb = new RigidBody ();
    MyScript ms = new MyScript();
     
  6. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,926
    Look at it from Unity's point of view. A Rigidbody can never be stand-alone. It has to always be in the Component list of 1 gameObject. So, Unity made
    g1.AddComponent<Rigidbody>()
    . It runs
    new
    , adds it to g1's list, sets the backpointer to g1, and runs any other set-up. Then they made
    new Rigidbody()
    an error since you wouldn't want to do only that, to get some useless free-floating rigidbody.

    Of course, you hardly need to do that. Dragging it on is easier. If you think you might need something later, it's usually simpler to make it beforehand and leave it disabled until you need it.

    The second GetComponent is a shortcut. GameObjects have the real one. They search their list for that component. Technically, a rigidbody should jump to it's gameObject and run it: gameObject.GetComponent. But Unity added a shortcut.
     
  7. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    685
    I always wondered about why every GameObject (even an "empty" one) automatically has a Transform. Seems like empty ones shouldn't need them. But maybe there's some kind of standardization behind the scenes in which it makes sense to assign one regardless?
     
  8. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,735
    "Empty" GameObjects are actually used often solely for the fact that they have a Transform component. For example you might use an empty GameObject at the tip of a gun barrel to keep track of where bullets are supposed to come from.

    But yeah sometimes you don't need a transform but it's there anyway. Like if you have a GameManager-type object. It's just a quirk of the engine that is convenient most of the time, and pretty irrelevant otherwise.
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,971
    It makes for a handy place to write down parenting info. Every GameObject has to be parented to something, even if that something is null, so why not have that in a Component, and why not make it a Transform.

    Honestly the most useful thing about having every object with a Transform is you can obtain a quick list of all your children recursively with a
    .GetComponentsInChildren<Transform>()
    and use that as the basis for runtime introspection of portions of your scene.
     
  10. psykick1

    psykick1

    Joined:
    May 19, 2020
    Posts:
    61
    Welcome to my club.

    After digging deep in google in the small hours of the night , I found unity component class that's show what happend in background.

    We can see the following things:
    1. Transform is a property of Component , it now make sense why we can type "transform" in our script
    (Our Script derived from behavior >> Monobehaviour >> Component.

    2. gameObject is a property of Component.

    3. GetComponent method inside Component returns the component inside gameObject.
    (this is make sense).

    What I cannot find in the component class is how it "Connected" to specific GameObject... (and how the properties gameObject + transform , is set to the specific one).


    Code (CSharp):
    1. // Unity C# reference source
    2. // Copyright (c) Unity Technologies. For terms of use, see
    3. // https://unity3d.com/legal/licenses/Unity_Reference_Only_License
    4.  
    5. using UnityEngine.Internal;
    6. using UnityEngineInternal;
    7. using UnityEngine.Bindings;
    8. using UnityEngine.Scripting;
    9.  
    10. using System;
    11. using System.Collections.Generic;
    12.  
    13. namespace UnityEngine
    14. {
    15.     [RequiredByNativeCode]
    16.     [NativeClass("Unity::Component")]
    17.     [NativeHeader("Runtime/Export/Scripting/Component.bindings.h")]
    18.     public partial class Component : UnityEngine.Object
    19.     {
    20.         public extern Transform transform
    21.         {
    22.             [FreeFunction("GetTransform", HasExplicitThis = true, ThrowsException = true)]
    23.             get;
    24.         }
    25.  
    26.         public extern GameObject gameObject
    27.         {
    28.             [FreeFunction("GetGameObject", HasExplicitThis = true)]
    29.             get;
    30.         }
    31.  
    32.         [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
    33.         public Component GetComponent(Type type)
    34.         {
    35.             return gameObject.GetComponent(type);
    36.         }
    37.  
    38.         [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
    39.         extern internal void GetComponentFastPath(System.Type type, IntPtr oneFurtherThanResultValue);
    40.  
    41.         [System.Security.SecuritySafeCritical]
    42.         public unsafe T GetComponent<T>()
    43.         {
    44.             var h = new CastHelper<T>();
    45.             GetComponentFastPath(typeof(T), new System.IntPtr(&h.onePointerFurtherThanT));
    46.             return h.t;
    47.         }
    48.  
    49.         [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
    50.         public bool TryGetComponent(Type type, out Component component)
    51.         {
    52.             return gameObject.TryGetComponent(type, out component);
    53.         }
    54.  
    55.         [System.Security.SecuritySafeCritical]
    56.         public unsafe bool TryGetComponent<T>(out T component)
    57.         {
    58.             return gameObject.TryGetComponent(out component);
    59.         }
    60.  
    61.         [FreeFunction(HasExplicitThis = true)]
    62.         extern public Component GetComponent(string type);
    63.  
    64.         [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
    65.         public Component GetComponentInChildren(Type t, bool includeInactive)
    66.         {
    67.             return gameObject.GetComponentInChildren(t, includeInactive);
    68.         }
    69.  
    70.         [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
    71.         public Component GetComponentInChildren(Type t)
    72.         {
    73.             return GetComponentInChildren(t, false);
    74.         }
    75.  
    76.         public T GetComponentInChildren<T>([DefaultValue("false")] bool includeInactive)
    77.         {
    78.             return (T)(object)GetComponentInChildren(typeof(T), includeInactive);
    79.         }
    80.  
    81.         [ExcludeFromDocs]
    82.         public T GetComponentInChildren<T>()
    83.         {
    84.             return (T)(object)GetComponentInChildren(typeof(T), false);
    85.         }
    86.  
    87.         public Component[] GetComponentsInChildren(Type t, bool includeInactive)
    88.         {
    89.             return gameObject.GetComponentsInChildren(t, includeInactive);
    90.         }
    91.  
    92.         [ExcludeFromDocs]
    93.         public Component[] GetComponentsInChildren(Type t)
    94.         {
    95.             return gameObject.GetComponentsInChildren(t, false);
    96.         }
    97.  
    98.         public T[] GetComponentsInChildren<T>(bool includeInactive)
    99.         {
    100.             return gameObject.GetComponentsInChildren<T>(includeInactive);
    101.         }
    102.  
    103.         public void GetComponentsInChildren<T>(bool includeInactive, List<T> result)
    104.         {
    105.             gameObject.GetComponentsInChildren<T>(includeInactive, result);
    106.         }
    107.  
    108.         public T[] GetComponentsInChildren<T>()
    109.         {
    110.             return GetComponentsInChildren<T>(false);
    111.         }
    112.  
    113.         public void GetComponentsInChildren<T>(List<T> results)
    114.         {
    115.             GetComponentsInChildren<T>(false, results);
    116.         }
    117.  
    118.         [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)]
    119.         public Component GetComponentInParent(Type t)
    120.         {
    121.             return gameObject.GetComponentInParent(t);
    122.         }
    123.  
    124.         public T GetComponentInParent<T>()
    125.         {
    126.             return (T)(object)GetComponentInParent(typeof(T));
    127.         }
    128.  
    129.         public Component[] GetComponentsInParent(Type t, [DefaultValue("false")] bool includeInactive)
    130.         {
    131.             return gameObject.GetComponentsInParent(t, includeInactive);
    132.         }
    133.  
    134.         [ExcludeFromDocs]
    135.         public Component[] GetComponentsInParent(Type t)
    136.         {
    137.             return GetComponentsInParent(t, false);
    138.         }
    139.  
    140.         public T[] GetComponentsInParent<T>(bool includeInactive)
    141.         {
    142.             return gameObject.GetComponentsInParent<T>(includeInactive);
    143.         }
    144.  
    145.         public void GetComponentsInParent<T>(bool includeInactive, List<T> results)
    146.         {
    147.             gameObject.GetComponentsInParent(includeInactive, results);
    148.         }
    149.  
    150.         public T[] GetComponentsInParent<T>()
    151.         {
    152.             return GetComponentsInParent<T>(false);
    153.         }
    154.  
    155.         public Component[] GetComponents(Type type)
    156.         {
    157.             return gameObject.GetComponents(type);
    158.         }
    159.  
    160.         [FreeFunction(HasExplicitThis = true, ThrowsException = true)]
    161.         extern private void GetComponentsForListInternal(Type searchType, object resultList);
    162.  
    163.         public void GetComponents(Type type, List<Component> results)
    164.         {
    165.             GetComponentsForListInternal(type, results);
    166.         }
    167.  
    168.         public void GetComponents<T>(List<T> results)
    169.         {
    170.             GetComponentsForListInternal(typeof(T), results);
    171.         }
    172.  
    173.         public string tag
    174.         {
    175.             get { return gameObject.tag; }
    176.             set { gameObject.tag = value; }
    177.         }
    178.  
    179.         public T[] GetComponents<T>()
    180.         {
    181.             return gameObject.GetComponents<T>();
    182.         }
    183.  
    184.         public bool CompareTag(string tag)
    185.         {
    186.             return gameObject.CompareTag(tag);
    187.         }
    188.  
    189.         [FreeFunction(HasExplicitThis = true)]
    190.         extern internal Component GetCoupledComponent();
    191.  
    192.         [FreeFunction(HasExplicitThis = true)]
    193.         extern internal bool IsCoupledComponent();
    194.  
    195.         [FreeFunction(HasExplicitThis = true)]
    196.         extern public void SendMessageUpwards(string methodName, [DefaultValue("null")] object value, [DefaultValue("SendMessageOptions.RequireReceiver")] SendMessageOptions options);
    197.  
    198.         [ExcludeFromDocs]
    199.         public void SendMessageUpwards(string methodName, object value)
    200.         {
    201.             SendMessageUpwards(methodName, value, SendMessageOptions.RequireReceiver);
    202.         }
    203.  
    204.         [ExcludeFromDocs]
    205.         public void SendMessageUpwards(string methodName)
    206.         {
    207.             SendMessageUpwards(methodName, null, SendMessageOptions.RequireReceiver);
    208.         }
    209.  
    210.         public void SendMessageUpwards(string methodName, SendMessageOptions options)
    211.         {
    212.             SendMessageUpwards(methodName, null, options);
    213.         }
    214.  
    215.         public void SendMessage(string methodName, object value)
    216.         {
    217.             SendMessage(methodName, value, SendMessageOptions.RequireReceiver);
    218.         }
    219.  
    220.         public void SendMessage(string methodName)
    221.         {
    222.             SendMessage(methodName, null, SendMessageOptions.RequireReceiver);
    223.         }
    224.  
    225.         [FreeFunction("SendMessage", HasExplicitThis = true)]
    226.         extern public void SendMessage(string methodName, object value, SendMessageOptions options);
    227.  
    228.         public void SendMessage(string methodName, SendMessageOptions options)
    229.         {
    230.             SendMessage(methodName, null, options);
    231.         }
    232.  
    233.         [FreeFunction("BroadcastMessage", HasExplicitThis = true)]
    234.         extern public void BroadcastMessage(string methodName, [DefaultValue("null")] object parameter, [DefaultValue("SendMessageOptions.RequireReceiver")] SendMessageOptions options);
    235.  
    236.         [ExcludeFromDocs]
    237.         public void BroadcastMessage(string methodName, object parameter)
    238.         {
    239.             BroadcastMessage(methodName, parameter, SendMessageOptions.RequireReceiver);
    240.         }
    241.  
    242.         [ExcludeFromDocs]
    243.         public void BroadcastMessage(string methodName)
    244.         {
    245.             BroadcastMessage(methodName, null, SendMessageOptions.RequireReceiver);
    246.         }
    247.  
    248.         public void BroadcastMessage(string methodName, SendMessageOptions options)
    249.         {
    250.             BroadcastMessage(methodName, null, options);
    251.         }
    252.     }
    253. }
     
  11. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,735
    This is part of the (closed source) C++ Unity engine. It doesn't exist in the C# scripting engine.
     
  12. psykick1

    psykick1

    Joined:
    May 19, 2020
    Posts:
    61
    Ok thanks
    But in general Am I right about the 3 points mentioned?
     
  13. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,735
    Yes.
     
    Last edited: Jun 22, 2020
  14. psykick1

    psykick1

    Joined:
    May 19, 2020
    Posts:
    61
    Ok thank you.