Any way to 'GetComponent' as a base class?

Let's say I have a base class like 'animal' and 3 subclasess like 'dog', 'cat', 'bird' Let's say the base has a function 'speak' that all 3 subclasses implement (bark, meow, chirp).

Then these get added to prefabs.

Now, I'd like to have a script be able to access the script component and call 'speak' and whatever the subclass happens to be, it will make the corresponding sound. Follow?

So, can I just call gameObj.GetComponent(Animal).speak() ?? I would think Unity expects the exact class name (subclass), or GetComponent will fail.

In short I believe it (`gameObj.GetComponent(Animal).speak()`) should work, but it may not work with the non-typed versions of GetComponent like that. Here's what I've done that seems to work.

I've got a Component Damageable that extends Monobehaviour. From that I have 2 components that extend from Damageable. DroneHealth and ShipHealth.

DroneHealth and ShipHealth are attached to prefabs. In my collision test code I do

Damageable damagable = gotHit.transform.parent.GetComponent<Damageable>();

To get the component (the DroneHeralth or ShipHealth component that is, I never attach the Damageable component to anything).

I then call applyDamage, which has the signature `public virtual void applyDamage(float amount, NetworkPlayer fromPlayer)` in Damageable (and is overridden in the child classes) via RPC and the correct override in the subclass gets called (I was suprised this worked by RPC when I tested it, but it does. If it works that way I'm pretty sure it'll work for local calls).

Bare bones versions of the components

using UnityEngine;
using System.Collections;

public class Damageable : MonoBehaviour
{

    private float inVulnDuration = 0.0f;
    private float inVulnStart = 0.0f;

    protected bool damagable = true;
    public bool Damagable
    {
        get { return damagable; }
    }

    protected virtual void Update()
    {
        // if invulnerable 
        if (!damagable)
        {
            //check and see if we should become damageable yet
            if ((inVulnStart + inVulnDuration) < Time.timeSinceLevelLoad)
            {
                damagable = true;
            }
        }
    }

    [RPC]
    public virtual void applyDamage(float amount, NetworkPlayer fromPlayer)
    {
        Debug.Log(": " + "applyDamage in Damagable ");
    }
}

using UnityEngine;
using System.Collections;

public class ShipHealth : Damageable
{
    protected override void Update()
    {
        base.Update();
        // if invulnerable 
        if (!damagable)
        {
            // code to make ship blink when invulnerable
        }
    }

    [RPC]
    public override void applyDamage(float amount, NetworkPlayer fromPlayer)
    {
            Debug.Log(": " +"applyDamage in shipHelath");
    }
}

Sounds like you should be using SendMessage.

gameObj.SendMessage("Speak");

In that case it doesn't matter what the component is called.