Inheriting a base variable to derived class

I want the base class to find a reference to the players inventory script. I then would like the base script to either have its variable playerInv be equal to the base classes or just inherit it. Can this be done without having to create a static reference somewhere. Or what is the most efficient possibility.

I was just wondering if there is a way to do this

public abstract class Item : MonoBehaviour 
{
    public Inventory playerInv = GameObject.Find("Player").GetComponent<Inventory>();
    public string name;
    public Item(string _name) 
    {
        this.name = _name;
    }

    protected virtual void Use()
    {
    }
}


public class Water : Item
{
    public Water(string name) : base(name)
    {
        //playerInv = base.playerInv;
    }

    protected override void Use()
    {
        Transform player = GameObject.FindGameObjectWithTag("Player").transform;
        RoomPlayer roomPlayer = player.GetComponent<RoomPlayer>();
        roomPlayer.Health += 25;
        //player.GetComponent<Inventory>().RemoveItem(this);  //last resort
        base.playerInv.RemoveItem(this); //can I do something like this? 
    }
}

by the way I realise that the below doesn’t work, it was just experimentation.

public`` Inventory playerInv = GameObject.Find(``"Player"``)``.``GetComponent``<Inventory>``(``);

For starters, I see in your Item class you are attempting to use a constructor with a MonoBehaviour component. This isn’t correct, MonoBehaviours should be added to gameObjects as components and initialisation should be done within the Start() and Awake() functions.

You can make the Start() and Awake() functions protected virtual void to make full use of polymorphism. If you then want your child classes to inherit the default values of the parent, you call base.Start() or base.Awake() in the corressponding start and awake functions within the child script.

Because “Water” inherits from “Item”, Water now contains all member variables of the parent which are not private. Therefore, Water already has a playerInv variable. So you can just use, playerInv.RemoveItem(this);

I already tried what you listed and it didn’t work. It kept declaring that it was null. I am also not attaching it to a game object hence the use of abstract class. I will fiddle around with the Start and Awake idea.

so the protected virtual start() and initialisation worked there. Thanks a bunch for that. I was wondering if this takes more processing power? As in during each initialising is it resetting the derived variables with base variables or are they all running off just base variables. Sorry I realised that having a constructor was stupid too, old habbits of my CS days die hard.

But you WILL be attaching child scripts to gameObjects. You won’t be calling Water water = new Water(“random”); You will be using AddComponent() etc. so the constructor is pointless.

public abstract class Item : MonoBehaviour 

{

     protected Inventory playerInv;
     protected GameObject player;



 
    protected virtual void Start()
    {
      //I am actually not sure you can provide any implementation in an abstract class?
      //anyway
      player = GameObject.FindGameObjectWithTag("Player");
      playerInv = player.GetComponent<Inventory>();
    }
    protected virtual void Use()

    {

    }

}

 

 

public class Water : Item

{


    protected override void Start()  
   { 
      base.Start();
   } 

    protected override void Use()

    {

        

        RoomPlayer roomPlayer = player.GetComponent<RoomPlayer>();

        roomPlayer.Health += 25;

        //player.GetComponent<Inventory>().RemoveItem(this);  //last resort

         playerInv.RemoveItem(this); 

    }

}

Like I wrote in a comment, I am not 100% sure you can actually provide any implementation in an abstract class, if this is the case, then either subclass it again with a base class which contains default functionality, or just make the abstract class a normal class with the default functionality.

I also just realised I already did have the correct answer like you said, but I think I must have been overwriting something or I honestly have no idea why it wasn’t working. My prior test had all declarations in Start yet the base script wasn’t recognising them, but now they are. Go figure. Thank you for your kind adoration.

If you don’t want a derived class to keep the default values, don’t call the base.Start(). If you need some values the same and others different, then calling base.Start() then resetting variables after that call will essentially overwrite them, this is all loading overhead so there is not really a need to worry about how much processing it takes. Especially when you are only changing the values of simple data types.

Ironically I was calling “Water water = new Water(“random”);”. I was creating a method system based on an imaginary game object that acted like psuedo fabricated game objects. It was a theory in futility. I think just putting everything as an empty game object prefab worked out fine, a little long winded for what I originally wanted but it ensures not complete randomness and at least a safety net.