Search Unity

  1. Click here to see what's on sale for the "Best of Super Sale" on the Asset Store
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Help Wanted Inheritance

Discussion in 'Scripting' started by liquidsht, Aug 28, 2020.

  1. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    If Class B is inheriting from Class A, and Class C inherits from Class B.
    What namespace is Class C now under? I want to access Class C from another script but I dont know what to put at the top using...
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    1,741
    Unless you manually create namespaces Unity should automatically include all of your own scripts for you to use, without you having to write the using directive at the top of the script.

    In your example i assume class A is inside some custom created namespace. Is there a reason why your example is 3 levels deep, ie C : B : A? Unless i'm missing something the same question could be asked for B : A, where A is part of some namespace and B is not (or optionally in a different namespace)?
    Anyways, in this case, if i understood you correctly, you will have to mention the namespace for the class definition of B, since otherwise it wouldnt know where the A it inherits comes from. Class B can then be accessed as a standalone.. in whatever namespace it may be in, if any. Namespaces are just containers for logically connected fragments of code.

    Hope this helps.
     
  3. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    I am using an ass
    Thanks for the reply. Actually I think I only have 2 levels of inheritance. I am using an asset that has the health script(Class A), with another asset, to trigger a screen shake I extended using another script(Class B). Now I am trying to write a script for my save manager. So in my save manager script, I am trying to access Class B for the health with getcomponent. I added all the namespaces but my save manager still cant access it. Is there another way to access it?
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    5,169
    There's no relation between what type a type inherits from and what namespace it is in.

    In this case:

    Code (csharp):
    1. namespace Foo {
    2.     public class A : B {
    3.  
    4.     }
    5. }
    A is in the namespace Foo. What namespace B is in doesn't matter.

    If B has a namespace other than Foo, you have to import it (using...) in order for the above to compile.

    You can access fields and methods that A inherits from B, even if you don't have B's namespace imported.
     
    Bunny83 likes this.
  5. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    1,479
    By "can't access it", do you mean the script cannot compile because it cannot reference the type name of the class, or that
    null
    is returned when you try to get an instance of Script B with
    GetComponent
    ?

    The latter problem is not a namespace issue, and as mentioned above, namespaces have no relationship with class inheritance or anything - they're just a way to logically group types under one name, like how
    List
    ,
    HashSet
    ,
    Queue
    ,
    Stack
    , etc. are all grouped under the
    System.Collections.Generic
    namespace, because they're all collection types that use generics.

    You can name a namespace whatever you want.
     
  6. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,231
    Obviously, if C is in B which is in A, then C is in the "namespace" A.B. Classes act as like namespaces. The problem is that a normal C# using is only for official namespaces. A newer rule allows it for classes by adding "static" in front.
    using static A.C;
    will allow your code "naked" use of C and anything else inside of B. The name is confusing. The idea is to let you use static variables inside of A.B, but it works for classes, or enumerations or delegates ... anything inside.
     
    Last edited: Aug 28, 2020
  7. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    by can’t access I mean it cannot reference it.
     
  8. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    1,479
    Does the script compile?
     
  9. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    No it doesn’t. I tested if I enter Health(class A) then it doesn’t show an error, but if I enter Healthwithscreenshake (Class B) then it says it doesn’t exist in the name space.
    I assumed unity would either
    A) finds the script on its own or
    B) since Class B inherited from Class A, they would be in the same name space? But it’s doing neither
    Sorry I am out now, otherwise would post code.
     
  10. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    1,479
    When that error comes up, Visual Studio (I'm assuming is what you're using) will show a little light bulb icon when you click on the line with the error.
    Click that icon and it will give you suggestions for fixes - the first of which will likely be to import the correct namespace.

    Clicking on the suggested fix will automatically import the namespace for you.
     
  11. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    Ahhh ok, thanks let me try that when I get home.
     
  12. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,231
    The thing is, there shouldn't be any problem. Since there is, you did something weird. For example, this will work fine:
    Code (CSharp):
    1. public class Cat : Animal { ...
    Anyone, anywhere, can use Cat. It isn't in any namespace and there's no way it could "accidentally" be in one. Not unless you had:
    Code (CSharp):
    1. namespace ZooStuff {
    2.   ...
    3.   ... lots more lines
    4.   public class Cat : Animal {
    But even then it's just a matter of looking and seeing "opps ... forgot I added that namespace up there".

    You might have them inside of each other, but that's weird since it makes it hard to put Cat on gameObjects:
    Code (CSharp):
    1. public class Animal : Monobehavoir {
    2.   public class Cat : Animal {
    If you did that, then you'd need
    Animal.Cat
    . But it would be better to not to put Cat inside of Animal.

    Did you see some advice about using namespaces, try it out, and it made this mess? If so, it might be easier to just delete them all. It's like if someone suggests a good screwdriver. Either you're "oh, that would make some jobs easier" or "what are screws? Guess I'll use it and find out".
     
  13. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    Sorry I didnt get back earlier, this is the original class:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using MoreMountains.Tools;
    4. using MoreMountains.Feedbacks;
    5.  
    6. namespace MoreMountains.CorgiEngine
    7. {
    8.    AddComponentMenu("Corgi Engine/Character/Core/Health")]
    9.     public class Health : MonoBehaviour
    10.     {

    and this is the class that inherits from health:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Com.LuisPedroFonseca.ProCamera2D;
    5. using MoreMountains.Feedbacks;
    6. using MoreMountains.Tools;
    7. using MoreMountains.CorgiEngine;
    8.  
    9.  
    10.  
    11.  
    12.     public class HealthWithCameraShakeExtension : Health
    13.     {
    14.        protected override void Start()
    15.             {
    16.                 base.Start();
    17.             }
    18.          
    19.         public override void DamageDisabled()
    20.         {
    21.             _animator.SetTrigger("Hurt");
    22.             TemporaryInvulnerable = true;
    23.             ProCamera2DShake.Instance.Shake("GunShot");
    24.             Debug.Log("Screen Shake");          
    25.         }
    So I am trying to access the class HealthWithCameraShakeExtension in my Save Manager.
    I am getting this type of namespace name could not be found error in Visual Studio.
    I tried the show potential fix Vryken suggested and it shows generate the class, which i dont think would fix the problem. Thanks.
     
  14. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,754
    There shouldn't be any problem accessing the script, because you did not specify a namespace explicitly, which means it'll end up in the global namespace. Unless you removed some important lines.

    You should add the script that is trying to use your halt component to your post - just to make it easier for the people to reason about your code.

    Also make sure there are no other compilation errors. Sometimes there're errors that occur as a consequence of other errors.

    Please also include the entire error message(s).
     
  15. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    Thanks Suddoha, this is the save manager I am using that is trying to assess the script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using MoreMountains.Tools;
    4. using System.Collections.Generic;
    5. using MoreMountains.InventoryEngine;
    6. using UnityEngine.SceneManagement;
    7. using MoreMountains.Tools;
    8. using MoreMountains.CorgiEngine;
    9. namespace MoreMountains.CorgiEngine
    10. {
    11.     public class Monobehavior
    12.     {
    13.         HealthWithCameraShakeExtension healthWithCameraShakeExtension;
    I am getting the error: the type or namspace name'HealthWithCameraShakeExtension' could not be found (are you missing a directive or assembly reference?

    There are no other errors on my script as this is unfortunately the first line of code I put in.
     
    Last edited: Aug 31, 2020
  16. mopthrow

    mopthrow

    Joined:
    May 8, 2020
    Posts:
    32
    Code (CSharp):
    1. I am getting the error: the type or namspace name'HealthWithCameraShakeExtnesion' could not be found (are you missing a directive or assembly reference?
    Assuming you copy pasted the error code, Extension is spelled incorrectly (Extnesion). Not sure why it's fine in the script and wrong in the error message.

    Does the error refer to a misspelled type in a different script?
     
  17. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    Sorry i typed the error code, the script was copied from the actual class. Fixed.
     
  18. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    639
    Are you using assembly definitions anywhere? If your "Monobehavior" script and your HealthWithCameraShakeExtension script are in different assembly definitions, and Monobehavior's asmdef has no reference to whatever asmdef HealthWithCameraShakeExtension belongs to, then you will get this error.
     
  19. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    Hmmm... I am not sure what assembly definition is so I assume no, unless it could be setup accidentally?
    I can access the Health class with no issues, its just the 'HeatlhWithCameraShakeExtension' class that inherits from Health Class that I cant access.
    the 'HeatlhWithCameraShakeExtension' just sits in my scripts folder under Assets.
     
  20. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,231
    Unless there's more,
    using namespace MoreMountains.CorgiEngine
    isn't needed -- everything is already being put inside of that namespace in the next line, so can see it. Other oddness, in the previous script Start doesn't need to (or can't?) be protected and override. It seems as if it should, be Unity finds them through reflection. But I don't think either of those cause this problem.

    If seems like a "turn off then on again" problem, since it should be fine. Can the inside of "Monobehavior" find any globals? And if Intellisense is working, simply typing HealthWi in a few places can quickly clear things up.
     
  21. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    The save manager i am using is also part of the Corgi Engine asset, hence it also uses the MoreMountains.CorgiEngine namespace, but like you said as long as the namespace is being imported, it shouldnt matter?
    That's the thing. If I just enter 'Hea', then it would suggest the Health class, which I would assume to be in the same namespace as the HealthWithCameraShakeExtension, but when i type in HealthWith, intellisense doesnt suggest it.
    To confirm, HealthWithCameraShakeExtension class should be under the same namespace as Health class right?
     
  22. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,231
    Should has 2 meanings. For #1, I'm not sure what you should attempt to put in which namespace. Maybe both classes should be in some other namespace and merely use stuff from Corgi. For meaning #2, you put the Health class in there (since it's wrapped in a namespace{}), but your HWCSE class isn't (not wrapped in namspace Corgi {}). I think your original Q was whether you inherit namespaces -- as was answered before, you don't, and that's on purpose and not a screw-up of C#. You should be able to find HWCSE from any fresh script.

    You might try taking Health out of the namespace. Or make quick toy classes A, B:A and C { B n; } to see if you can duplicate the problem.
     
  23. liquidsht

    liquidsht

    Joined:
    Jun 4, 2020
    Posts:
    47
    OK i just tested it, i can access the HWCSE class from a normal Monobehaviour script.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5.  
    6. public class PlayerPos : MonoBehaviour
    7. {
    8.     HealthWithCameraShakeExtension healthWithCameraShakeExtension;
    9.     private GameMaster gm;
    This picks up HWCSE class just fine.
    So looks like the problem is in the Save manager, it is not access anything that I can access normally in standard Monobehaviour?
    Is there a way I can access it like you normally would with namespace.Class.xxx?
     
unityunity