Search Unity

General Question on GameObject.GetComponent<Whatever>();

Discussion in 'Scripting' started by eagreen, May 27, 2017.

  1. eagreen

    eagreen

    Joined:
    May 27, 2017
    Posts:
    1
    Hi there

    I'm new to Unity but i'm pretty experienced in Microcontrollers (C).
    Scripting itself isnt a problem, but i'm having trouble in understanding how different Gameobjects interact with each other.

    I'm currently following a tutorial on a basic FPS in Unity, the tutorial is scripting in Java but yet i was able to do it in c#.

    I made a crosshair that expands a little when i shoot. Each crosshair line has an animation attached that moves it a little to the outside and back.
    upload_2017-5-27_19-24-37.png

    I got a Gameobject holding my Script that triggers the animations.

    public class CrossAnimate : MonoBehaviour {

    public GameObject UpCurs, DownCurs, LeftCurs, RightCurs;
    private Animation UpCursAnim, DownCursAnim, LeftCursAnim, RightCursAnim;

    private void Start()
    {
    UpCursAnim = UpCurs.GetComponent<Animation>();
    DownCursAnim = DownCurs.GetComponent<Animation>();
    LeftCursAnim = LeftCurs.GetComponent<Animation>();
    RightCursAnim = RightCurs.GetComponent<Animation>();
    }

    // Update is called once per frame


    void Update ()
    {
    if (Input.GetButtonDown("Fire1"))
    {
    UpCursAnim.Play("UpCurs");
    DownCursAnim.Play();
    LeftCursAnim.Play();
    RightCursAnim.Play();
    }
    }
    }


    Its working thats not my problem, i just dont get why its working this way.
    The crosshair animation is attached to the corresponding crosshair line, the corresponding crosshair line is attached (dragged&dropped) to the scripts GameObjects.

    What i dont understand is why cant i trigger the animations from the GameObject that is attached to the script [for example UpCurs.Animation.Play()] directly?

    i know i have to
    UpCursAnim = UpCurs.GetComponent<Animation>();
    and then
    UpCursAnim.Play("UpCurs");

    in my understanding the line UpCursAnim = UpCurs.GetComponent<Animation>(); copies the content of the Animation member of Gameobject UpCurs into a new Animation class without any relation to the origin.

    Why is the origin of the content executed/changed when i execute/change the "copy" of it?
    And why isnt it working when i try to do it directly?

    In my understanding of programming the origin shouldnt be affected when i do anything to UpCursAnim, but in this script it is.
    The script is exactly doing what is should, but not getting why it does gives me a headache :mad:

    Thank you in advance for answering my probably stupid question
     

    Attached Files:

  2. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,304
    First things first, use code tags
    https://forum.unity3d.com/threads/using-code-tags-properly.143875/

    You're wrong. It's a pointer to the same place in memory. It's the original.

    What do you mean?
     
  3. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    Pretty sure you meant UnityScript, which is a form of JavaScript, which is a completely different language from Java!

    You can you just need the reference to the object.

    No it doesn't copy the content. it passes a reference. You are working with the exact instance that is on that gameobject.

    What have you tried to do it directly?

    Edit:

    looking closer I think you tried something like

    Code (CSharp):
    1.  
    2. UpCurs.Animation.Play();
    3.  
    So your question is more about "Why does something like GetComponent exist and why do I have to use it?".

    The GameObject follows the Mediator Design Pattern so it holds its Components separately from each other. this encourages a Composition style of development and it helps keeps these components decoupled. It promotes a Separation of Concerns style of programming.

    Not every GameObject is going to have an Animation component, not every Gameobject is going have whatever Script you write. but when it does, you will need a clean way of accessing that component. and thats what GetComponent is about. This way GameObject's code doesn't get bogged down with specific types. If for example the Animation Component is removed and replaced with some similar class, the GameObject class won't break.

    Transform is a special case. Every GameObject will always have one. This is why you can do things like gameObject.transform. But if you really wanted to you can also use gameObject.GetComponent<Transform>() and it'll give the same thing
     
    Last edited: May 27, 2017
    Socrates likes this.
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Oops: My post uses "Animator" and the OP was using "Animation". But the same idea :) Realized this after.

    Just a small note, as you're new to Unity, I'm sure you'd come across this later on your own, anyways.
    You could have dragged & dropped the game object(s) with animator components directly into the animator variable slots inside the inspector (note: provided they were public or had the SerializeField attribtue). You needn't get the game objects, then look up their animators, too. It's not wrong, I'm just pointing this out as an option.

    You can also access the Animator from the game object on 1 line:
    Code (csharp):
    1.  gameObjectVariable.GetComponent<Animator>().Play();
    The syntax is a bit different than the one you asked "Why can't I do this directly?". :)
     
  5. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,997
    To expand on the two points above (about references): Java and C# use a dumbed-down system of implicit pointers. For anything declared as a class, every variable is a pointer. If it says it returns an Animation, it really returns a pointer to one. It's impossible to return an actual Animator object, because of how the language works.

    Most things written about this assume Java/C# is your first language, so don't explain it using general computer terms. My longer "C# for C++ users" is at taxesforcatses, with a section on how and why they use implicit pointers.