Polymorphism and interfaces

So I have two set of game objects: Damage Dealers and Damage Takers.

The former implements this interface:

public interface IDamageDealer
{
    int Damage { get; set; }
}

The latter implements this one:

interface IDamagable 
{
    void hitReg(IDamageDealer dd);
}

In the OnCollisionEnter methods of the DamageDealers I want to deal damage to a Game Object if it is a Damage Taker without knowing exactly what type of Damage Taker it is.

So I added a specific tag to the Damage Takers and tried to get their script component which implements the interface IDamageDealer:

void OnCollisionEnter(Collision collisionDetails) 
{
	GameObject other = collisionDetails.gameObject;
	
	if(other.tag == Constants.DAMAGABLE_TAG)
	{
		other.GetComponent<IDamagable>().hitReg(this.damage);
	}
	///...
}

This does not work since in Unity the type parameter of this method call must be of type `UnityEngine.Component.

Is there a generic built in way to deal with this situation un Unity?

In the meantime I added an extension method to solve my problem. I hope it helps someone:

public static class ExtensionMethods
{
    public static T GetComponentByInterface<T>(this GameObject go) where T : class
    {
        T ret = null;
        foreach (var component in go.GetComponents<MonoBehaviour>())
        {
            T current = component as T;
            if(current != null)
            {
                if (ret == null)
                    ret = current;
                else
                    throw new Exception(); // TODO: OWN EXCEPTION
            }
        }

        return ret;
    }
}

No, there isn’t a generic way but you can use the non generic function. The generic GetComponent is actually just a wrapper for the System.Type version.

So instead of

other.GetComponent<IDamagable>();

you can do

(IDamagable)other.GetComponent(typeof(IDamagable));

As extension method it could look like this:

public static T GetInterface<T>(this GameObject aGO) where T : class
{
    return aGO.GetComponent(typeof(T)) as T;
}
public static T GetInterface<T>(this Component aComponent)  where T : class
{
    return aComponent.GetComponent(typeof(T)) as T;
}

I’ve posted them a couple of times here on UA ^^

You could do:

 public abstract class IDamageDealer : MonoBehaviour
 {
     // your abstract stuff
 }

Of course this doesn’t work when you need to implement/derive more than two interfaces.