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

Issue with Base and Derived Class, Field is null when called with base keyword.

Discussion in 'Scripting' started by Titanhex09, Aug 22, 2022.

  1. Titanhex09

    Titanhex09

    Joined:
    Feb 18, 2022
    Posts:
    3
    Here's what I'm trying to do:

    I have a base class (Base) and a derived class (Derived).

    Base has a field of TypeA called SomeType.
    Derived has a field of TypeB called SomeType.

    TypeA is the base class of TypeB.

    I wanted TypeB from Derived to override TypeA from SomeType.

    When I call the base virtual method from the derived override method, SomeType is null, indicating that it is still using the base.

    Here's the relevant class architecture:


    Code (CSharp):
    1.  
    2. namespace RPGCharacterAnims
    3. {
    4.     public  class RPGCharacterInputSystemController : MonoBehaviour
    5.     {
    6.         protected RPGCharacterController rpgCharacterController;
    7.  
    8. ...
    9.  
    10.       protected virtual void Moving()
    11.         {
    12.             moveInput = new Vector3(inputMovement.x, inputMovement.y, 0f);
    13.  
    14.             // Filter the 0.1 threshold of HasMoveInput.
    15.             if (HasMoveInput()) { rpgCharacterController.SetMoveInput(moveInput); }
    16.             else { rpgCharacterController.SetMoveInput(Vector3.zero); }
    17.         }
    18. ...
    19.    }
    20. }
    Code (csharp):
    1.  
    2.  
    3. namespace RPGCharacterAnims
    4. {
    5.     public class MyCharacterInputSystemController : RPGCharacterInputSystemController
    6.  
    7.         [SerializeField]
    8.         protected MyCharacterController rpgCharacterController;
    9. ...
    10.         protected override void Moving()
    11.         {
    12.             base.Moving();
    13.         }
    14. ...
    15.    }
    16. }
    This produces a null when checking for the rpgCharacterController in the base method, but the correct object in the derived method.

    I understand that pulling from a base that uses a different class can have issues, and is not ideal.
    I'm open to a better way to structure this.

    [EDITED: To remove [Serialize Field] from the field in Script A.]
     
    Last edited: Aug 23, 2022
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,725
    Why are you redefining the variable in the child class? That is hiding the one in the parent, and causing your entire issue. Delete line 8 in your second script.
     
    Bunny83 likes this.
  3. Titanhex09

    Titanhex09

    Joined:
    Feb 18, 2022
    Posts:
    3
    Thanks!

    While messing with the code architecture I overlooked this.

    Quick question, I accidently put in the code where it was serialized in Script A and B.

    However, I wanted the field to be Serialized in Script B but not in Script A.

    Is it possible to do this?
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,943
    With inheritance no, as that's the point of inheritance, that the child inherits the traits of the parent.
     
    Bunny83 likes this.
  5. Titanhex09

    Titanhex09

    Joined:
    Feb 18, 2022
    Posts:
    3
    Ah so the traits of the child cannot be altered once inherited? I thought inheritance could allow modification of the derived field's properties once inherited.

    I can just make the parent Serialized for my own purposes, but I wanted to avoid altering the parent.

    I'm extending a different author's script and bridging it's compatibility. I felt this would be useful for others should I want to share it. If I have to alter the base class, that drops its plug and play capability.

    Part of the change requires me to make the field assignable in the Unity Editor, since the base class uses GetComponent, but I wanted to make it so the Component doesn't have to be on the GameObject.

    (In this case, I want to separate the Character and Player, whereas the script demands that the Character and the Player be one GameObject)

    Is there another way to do this?
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,943
    You can override methods and properties that are marked as abstract or virtual. But fields belong to their bodies as-is, and just have different access modifiers.

    Whether a member is marked private, protected, public, etc, they still in exist in both parent and derived types, regardless of whether they're overridden or not.

    If the base class doesn't allow you to override this behaviour, you're SOoL and just need to make your own controller.
     
    Titanhex09 likes this.
  7. Greviouss

    Greviouss

    Joined:
    May 27, 2016
    Posts:
    120
    this can also happen if you are working with objects that are marked with monobehaviour in the parent class but not supposed to be...