I figured I would write a base Item class that implements a generic use(Dog dog) function. Then if a specific item wants to apply a certain functionality for a dog, it could override the function with a more specific dog type. For example TennisBall : Item has a use(GoldenRetriever dog). However, having written this it appears as if only the parent function is ever called.
In my Inventory class I have a reference to the dog based on the Dog class. When I log what the type of this Dog is, I get GoldenRetriever. Yet still the parent Item.use() function is called instead of the more concrete TennisBall.use() function. The reason for this is probably that Dog is what the instance is cast to, so it will call that (not quite sure why my Debug.Log still shows GoldenRetriever then).
I've tried specifying some interfaces to solve the problem also, but it seems that the problem persists. My feeling is that this rather has to do with the parameters in the methods than with anything else.
public class Inventory : MonoBehaviour {
...
private List<Item> items = new List<Item>();
private Dog dog;
public int activeItem = 0;
...
public void addItem(Item item) {
items.Add(item); // This is where the TennisBall item will be added
}
public void open(Dog dog) {
open();
this.dog = dog;
}
void Update() {
if (Input.GetKeyDown(KeyCode.E)) {
Debug.Log(dog); // Output: Golden Retriever (GoldenRetriever)
items[activeItem].use(dog);
}
}
}
Item:
public class Item : MonoBehaviour {
public void use(Dog dog) {
Debug.Log(dog); // Still Golden Retriever (GoldenRetriever)
throw new NotImplementedException();
}
}
TennisBall:
public class TennisBall : Item {
public void use(GoldenRetriever dog) {
Debug.Log("Doing something specifically for a Golden Retriever!"); // This never gets called
}
}
You can start with actually overriding the use function and using some type-testing in the override:
public class Item : MonoBehaviour {
public vitual void use(Dog dog) {
Debug.Log(dog); // Still Golden Retriever (GoldenRetriever)
throw new NotImplementedException();
}
}
public class TennisBall : Item {
public override void use(Dog dog) {
var goldenRetriever = dog as GoldenRetriever; // check if dog is of type GoldenRetriever
if(goldenRetriever != null)
{
Debug.Log("Doing something specifically for a Golden Retriever!"); // This never gets called
}
// your other logic....
}
}