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. Dismiss Notice

Using a subclass

Discussion in 'Scripting' started by A_Box, Dec 27, 2020.

  1. A_Box

    A_Box

    Joined:
    Feb 3, 2020
    Posts:
    62
    Hi
    I'm pretty new to programming, c# and unity. I'm trying to call a method of a subclass from the parent class.
    Shouldn't this work?

    Code (CSharp):
    1. public class MainCl: MonoBehaviour
    2. {
    3.     int a=0;
    4.     void start()
    5.     {      
    6.          SubCl test;
    7.          test.A();
    8.     }
    9. }
    10.  
    11.  
    12. public class SubCl : MainCl
    13. {
    14.     protected int b = 1;
    15.     public void A()
    16.     {
    17.      a+=b;
    18.      Debug.Log(a);
    19.     }
    20. }
    This should print "1" right? But it says "NullReferenceException: Object reference not set to an instance of an object MainCl.hello. Am i missing something?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Line 6 only makes the reference
    test
    . You still have to create one. Since it is a MonoBehavior you CANNOT call
    new
    to get one: you must use either GetComponent() to get an existing one or AddComponent() to make a new one.

    What are you trying to do? This inheritance silliness almost never required in Unity, and only certain people who enjoy pain typically go in for it, since the Unity MonoBehavior methods (Awake, Start, Update, etc.) are all rarely overridden, and by doing inheritance you are setting yourself up for countless future users of your code (including yourself) to forget to call the base method and cause all kinds of weird problems.

    I highly recommend sticking with a pure component ("has-a" rather than "is-a") architecture initially until you get a feel for what you're doing.
     
    A_Box likes this.
  3. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    In line 6 you only define the variable, but do not actually allocate an object use 'new' for that,
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,336
    Verboten when it is a MonoBehaviour-derived class. :)
     
  5. A_Box

    A_Box

    Joined:
    Feb 3, 2020
    Posts:
    62
    I tought that that was the best way to keep my script very readable, by putting variables that are used only for one specific function with the method they are used in in a separate class (like, a class that has 2 floats for height and base and a method to calculate a rectangle's area), or to just use a base structure that can be expanded in subclasses (like having a "enemy" class, and subclasses like "boss" or "special"). I should'have specified these things in the post (also the script that i posted was just an example of how i intended to use classes). But apparently the main problem is that i don't know how an "has-a" architecture looks like. Is that just using GetComponent or is it somthing else? Could you give me a quick example?
    Also if you suggest using other tipes of approaches for what i'm looking for please tell me, i'm still learning this stuff.
    Thanks
     
  6. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Inheritance should not be used for that kind of thing like your enemy / boss example. Let's say you introduce friendly NPC that has similar functionally to the enemy. Now your are trouble with inheritance.

    Or a real world example from our game. We have hand grenades in our game, we have a grenade component and a explosive component. Later on we wanted a C4 bomb, it has none of the grenade properties but it explodes just like a grenade.

    Also using a event aggregator we can trigger our explosion in an decoupled way. Now the handgranade can also be a smoke grenade with zero code change, just replace the Explosive component to a SmokeEmmiter component.
     
    mopthrow likes this.
  7. A_Box

    A_Box

    Joined:
    Feb 3, 2020
    Posts:
    62
    I get what you mean - and i also get that i have lots of more research to do, since i have no idea what an event aggregator is...
    thanks for the tip, i'll go ahead and look into it!
    So is there a case where using subclasses makes sense? If so, what kind of approach is needed?
     
  8. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Very seldom inheritance makes sense. In my example the explosive and smoke emiiter could share a abstract base class. But most of the time a interface will do since they don't share implementation details. And if they do it might be better fitted with another layer of composition instead of inheritance.

    Event aggregsgtion is just a way of letting component A push messages to component B without them knowing about eachother. My above example could also be achieved by letting component a (grenade) know about component b (explosive) doing

    GetComponent<IExplosive>(). Explode()

    Though a bit strange having a smoke emitter implementing IExplosive and a method Explode that starts emmiting smoke ;)
     
  9. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    You are using it wrong. :)
     
  10. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    The right way is not to use it. 99.9 procent of the time
     
  11. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    <looks at Unity's inheritance tree>
    <blank stare>
    <shakes head>
     
  12. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Every time you use a Monobehaviour you are using inheritance.
     
  13. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Yeah, would have been much better with a IComponent interface instead.

    You shouldn't use the Unity API to measure SDK quality :p
     
    Kurt-Dekker likes this.