What´s the cleanest way to link physics-events and gameobjects?

I’m looking for the “proper” way to organize my event handling code. I have a 2D game that detects mouseclicks on GameObjects with

 RaycastHit2d[] hits = Physics2D.RaycastAll(...)
 foreach(var hit in hits){
     // do something with hit.transform.gameobject
 }

I like this approach for its efficiency and flexibility for filtering of objects hit. My problem is, how do I route the click event back to a specific component? The example above works fine if I have one component called ClickHandler with a method CustomClick() that contains all the game’s click logic.

hit.transform.gameobject.GetComponent<ClickHandler>().Clicked(); 

But this is too simplistic; my game has several different components - terrain, buildings, animals, players - each needs to respond to a click in its own way. I want to avoid a mess of if statements :

 foreach(var hit in hits){
     if (hit.transform.gameobject.tag == "Terrain"){
         hit.transform.gameobject.GetComponent<Terrain>().Clicked()
     } else if (hit.transform.gameobject.tag == "Animal"){
         hit.transform.gameobject.GetComponent<Animal>().Clicked()
     } else {
        // ugh, repeat for each type, and remember to maintain this when new types added
     }
 }

The above works, but it’s hardly elegant coding. Also, I’m using tags just as an example - in reality I can’t assume an objects tag always corresponds to its event behavior. Unity’s components don’t do interface casting. I can use gameobject.SendMessage(“Clicked”), but that’s a performance killer. Any suggestions for a clean, fast solution to this?

You can do interface casting. However Unity’s generic GetComponent method has a constraint on “Component”. So you can only use type parameters which are derived from Component which interfaces of course aren’t.

I’ve posted two extension methods over here which essentially do exactly the same as Unity’s generic method, but don’t have the constraint.

As you might know you just have to create a static class somewhere in your project and insert those two methods in that static class. Now you can use those methods on any Component or GameObject reference.