Base Variables Not Available in Override Methods?

So, I’m having a weird issue with an inherited class. In the base class I have a variable - ‘inv’ - that is supposed to be available for all descended classes. (It’s of the “protected” type.) Now, in my descended class I can access this variable from the regular update function just fine. But I can’t seem to access it from within an override method. Here’s what the code looks like.

This is the base class:

public class Item : MonoBehaviour {
	
	public int itemID;
	public int price;
	public string itemName;
	public string itemDescription;
	
	protected GameObject control;
	protected PlayerInventory inv;
	
	// Use this for initialization
	void Awake () {
		control = GameObject.Find("GameController");
		inv = control.GetComponent<PlayerInventory>();
	}
	
	// Update is called once per frame
	void Update () {
	
	}
	
	virtual public bool UseItem() {
		return true;
	}
}

All well and good, fairly simple. As you can see, the relevant variable, ‘inv,’ is set to be the PlayerInventory script as part of the ‘awake’ method. Fine. Here’s the descended class:

public class ItemStatBoost : Item {
	
	public string statName;
	public int statID;
	
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
		Debug.Log ("inv (update): " + inv);
	}
	
	public override bool UseItem() {
		//prompt the user to pick a foozle
		int choice = 0;
		
		//get that foozle 
		Debug.Log ("inv: " + inv); //WHY CAN'T WE USE INV HERE, WHICH WE INHERIT FROM ITEM? IT DOESN'T MAKE SENSE!
		
		PlayerInventory invS = GameObject.Find("GameController").GetComponent<PlayerInventory>();
		ArrayList playerFoozles = invS.GetFoozles();
		GameObject chooseFooz = playerFoozles[choice] as GameObject;
		Foozle chF = chooseFooz.GetComponent<Foozle>();	
		
		//find the correct stat, and up it to max
		if (chF.currStats[statID] < chF.maxStats[statID]) {
			chF.currStats[statID] = chF.maxStats[statID];
			return true;
		}
		
		else return false;		
	}
}

The weird part is, the print statement in the update loop prints: “inv (update): GameController (PlayerInventory)”

BUT the print statement in the UseItem override method prints: "inv: " and that’s it. It doesn’t seem to register that the PlayerInventory script is attached to that variable. (Which is why I immediately get it again on the next line of the script.)

It’s silly for me to have to make a whole new variable and re-acquire the PlayerInventory script when that’s supposed to be the whole purpose of having the descended ‘inv’ variable in the first place. The only thing I can think of is that maybe there’s some kind of system whereby you can’t use base class variables in an override method? (For the record, I also tried using ‘base.inv’ and that doesn’t work either.) Is that the case? Or is there something else wrong here that I’m missing?

A simpler test case works fine for me. Nothing in your code seems to call UseItem, but I guess that happens from somewhere else. Maybe the context for that call is important but I can’t see why it would be.

Your derived class’s Update method will shadow the base class’s method. It doesn’t matter here as your base class Update() method is empty. But it illustrates a problem you’ll probably run into if you lean too hard on inheritance of MonoBehaviours. Think about whether you really need both bits of inheritance, and one way or another, consider making only one of your user classes attempt to imprement the magic entry points.

Do you think you could explain what you mean by shadowing the base class’s method? Like, they will both get run, or…?

Also, can you please elaborate on what the problem is that I will run into with inheritance? I do think I need inheritance in this particular case, but I want to understand what the downside/dangers are.

Thanks!

I just meant that the base class method will never get called, because the derived class implements its own version.

If your base class implements one subset of the Unity entry points and the derived class implements another subset, you need to be careful that they don’t both try to implement the same method, as Unity won’t call both of them. Making the base class methods protected or public will highlight the problem as the C# compiler will tell you you need to use “new” in the derived class, pointing out the clashing methods. More canonically, you can also make the base class methods virtual, and override them in the derived class, and then decide whether or not to chain through to the base implementation…