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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Help understanding types.... ?

Discussion in 'Scripting' started by ApteryxK, May 20, 2015.

  1. ApteryxK

    ApteryxK

    Joined:
    Feb 8, 2015
    Posts:
    40
    Hello I am learning Unity and I am getting more and more advanced now, but I only learned the theory and I have almost no practice.
    So right now, I am at the end of my book on C# and I started to make a summary of what I learned, I am trying to put all the knowledge together.
    But the problem is that I am still having trouble with understanding types...

    I feel like I am missing something.
    Basically what I understand is that when you make a class it becomes a new type.
    Ok, got that and a variable with this type will be like a class which inherits it so it will have every value it has. It is a nullable type right ?

    I got this but type casting is troubling me... I mean if you cast a type (a class type) to another type, you have to use a static public implicit operator right ?

    I think I got that too but it's getting obscure with GameObjects and stuff like that.

    In this code :
    Code (CSharp):
    1.  
    2. GameObject box =
    3. GameObject.CreatePrimitive(PrimitiveType.Cube);
    4. box.AddComponent("Monster");
    5. Monster m = box.GetComponent("Monster") as Monster;
    6.  
    We create a primitive type then assign it Monster, which is a component, a class.
    Then "Monster m = box.GetComponent("Monster") as Monster;" we instanciate it but I don't really understand here, where is the constructor ? why is there an "as Monster" ? what happens ? is it because it is generic ?
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    GetComponent doesn't need a constructor because you're just finding an object that already exists. Technically, the constructor is called from within .AddComponent. However, when dealing with MonoBehaviours (and Components in general), don't worry about constructors; you never see them or use them. Instead, you use Unity's functions (like AddComponent) to create objects. It's only if you use non-MonoBehaviour classes that you use constructors (either stuff like Vector3 [though it's technically a struct, but close enough] or your own custom classes, most commonly used to hold sets of data.)

    The reason you need 'as Monster' is because it's NOT generic - not in the C# sense of the word 'generic', which has a very specific meaning. When you call a function, it has a particular return type - in the case of GetComponent("Monster"), that return type is Component, because functions can't change their return type based on the parameter you feed them. So, you have to typecast that to Monster in order to use any of the members that the Monster class has. HOWEVER, there is a feature of C# called Generics, which allows someone to write one function or class, take a type as a special kind of parameter, and return that type (when, internally, the function/class doesn't know or need to know what type it's actually using).

    You should get used to using the Generic form of .AddComponent and GetComponent. It's faster in terms of performance, it's cleaner in terms of syntax (no need to typecast the result), and if you make a typo it'll alert you of that at compile time instead of runtime.
    Code (csharp):
    1. Monster m = box.GetComponent<Monster>();
    Sidenote: .AddComponent returns the component you just created. So your GetComponent call in this case is redundant
    Code (csharp):
    1. Monster m = box.AddComponent<Monster>();
     
    Last edited: May 20, 2015
    ApteryxK likes this.
  3. ApteryxK

    ApteryxK

    Joined:
    Feb 8, 2015
    Posts:
    40
    Oh my god, thank you so much, you enlightened my lantern.
    I see now, getcomponant gives you a componant and not a ...
    Wow thank you so much :D
    Yes, you are right, I took this code from my book though.
    And now I understand better thanks to your explanation and my knowledges about generic and type meet and I see better now.
    --
    And I would like to ask you a personnal question, you seem to be very active in the forum, why do you spend time on it, do you consider it as a hobby, do you like helping people, or like solving problems problems and getting experience from others problems' which get solved ? I am curious.
     
  4. ApteryxK

    ApteryxK

    Joined:
    Feb 8, 2015
    Posts:
    40
    Well here is another question, a Component is a type, and here we cast is as a Zombie, but how is this cast possible without a specific function.
    Because Component here is a special type ?
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    Old book? IIRC, Unity didn't have generic methods for these early on..... *checks API history* ..... wow, apparently not until version 3.3? That's much later than I thought!
     
    ApteryxK likes this.
  6. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    A Zombie is a MonoBehaviour and a MonoBehaviour is a Component
     
    ApteryxK likes this.
  7. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    The object that is returned by GetComponent("Zombie") is of type Component, but the thing that it points to is still whatever type it really is (Zombie). Your script doesn't know/can't rely on that, however - it sees that the function returns Component, and if you try to access component.isHungryForBrains, that's not a part of Component.

    But since the thing it's pointing to is, under the hood, still a Zombie (which inherits, somewhere down the chain, from Component), you can typecast it to a Zombie, and now your script knows that it has all these extra functions that Component doesn't have.
     
    ApteryxK likes this.
  8. ApteryxK

    ApteryxK

    Joined:
    Feb 8, 2015
    Posts:
    40
    No, it was teaching one thing at the time that's why.
    The studdent would get confused.
     
  9. ApteryxK

    ApteryxK

    Joined:
    Feb 8, 2015
    Posts:
    40
    So if I understood, Zombie is a Zombie type but also a Component type because of inheritance and by casting you actually just empathize the fact that is a zombie, you say how deep it is in the hierarchy ? :)
     
  10. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    It's hard to say without the context of the lesson, but I feel like that's a poor reason to teach that kind of usage of GetComponent. It's just going to give students bad habits that are harder to break later. Better to teach GetComponent<Monster>(), with a note of, "This is a special form of syntax called generic syntax, don't worry about what that is exactly right now, because we'll get to it later."
     
    ApteryxK likes this.
  11. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,744
    Pretty much correct.
     
    ApteryxK likes this.