A way to think about it once you’re getting the hung of it, is as if everything that would be written in Combatant you’d have it a the beggining of both your other scripts. So, if in Combatant you write int health =100; both the player and the Wolf will recognize this variable as if it was written above them. In fact in the inspector, in your Wolf component, you’lll see every Combatant variable, and after those, the once that are exclusive to the Wolf.
The same happens with methods. If you put a method in Combatant, both Wolf and Player have it right now, and you can call it as if it were declare in them.
If you have a method that only the player should have then write it in the Player script. If it’s shared by both, write it in the Combatant one.
If you have a Player myPlayer and you make this check if(this is Combatant) it’ll return true. The wolf script will do the same.
You can for example make a list List combatants; and Add your Wolf script and your Player script as if both were combatants scripts (they actually are, and again, they have everything that you’ve written in combatant in them).
Now, sometimes you’ll have a method that you want to have in both the Wolf and Player, let’s imagine for example a method TakeDamage(). Let’s make it simple: all it does is subrracting the health from the character
TakeDamage(int amount)
{ health -= amount}
Since you want both to have it, you put it in the Combatant class. But then you figure that when the player takes damage you also want blood to be splattered in the screen. You could put that to the method, but then when the Wolf gets damage it’ll also splatter the screen. A better approach could be to just go to the Combatante script and in TakeDamage() after what we wrote, add " if (this is Player){Splatter();}".
This will work, but then why use polymorphism? you could just as well put a bool isPlayer and forget about it.
Instead what you do in polymorphism is override TakeDamage().
So, you go to the Combatant script and in TakeDamage() you write the keyword “virtual”. This means that child classes can override the method {“ovewrite” = rewrite} it would look like this
//in your combatant class
public virtual void TakeDamage(int amount){
//The part of the method that will be shared between both Wolf and Player
}
your Wolf class don’t need any changes, since that method is fine for it. If you write inside of the Wolf class say at Start(){ TakeDamage(4);} it’ll take 4 points of damage.
Your Player class, on the other hand, you want to change a bit so what you do is this:
//override method in Player class
public override void TakeDamage(int amount)
{
//put this only if you want it take away the part of your health, if you don't put it, it'll just make the splatter and that'll be it.
base.TakeDamage(amount);
//Now, this part, only the player will have it:
Splatter();
}
Sometimes you want call the base class method. This is useful even though you don’t share a single line of code. Why? Imagine you have a list of Combatants that are in a fire trigger. They could be either Wolf or player, and they may react different to the explosion, but it’s useful to have a method that is share so you can do this
List<Combatants> combatantsInsideFire;
foreach (Combatant combatant in combatantsInsideFire)
{ combatant.ReactToFire();}
But in the cases were you don’t share any code you may consider to implement an interface instead, specially if you want to characters that react to fire that are not combatants, like bystenders for example.