Joe Blow Joe Blow - 1 year ago 65
C# Question

In Unity, how does Unity magically call all "Interfaces"?

Unity has an "interface" as they call it


You simply implement OnPointerDown ...

public class Whoa:MonoBehaviour,IPointerDownHandler
public void OnPointerDown (PointerEventData data)
{ Debug.Log("whoa!"); }

and Unity will "magically" call the
in any such MonoBehavior.

You do NOT have to register them, set an event, or do anything else.

All you do is add "IPointerDownHandler" and "public void OnPointerDown" to a class, and you can get those messages at all times magically.

(If you're not a Unity dev - it even works if you suddenly add one in the Editor while the game is running!)

How the hell do they do that?

How can I do that with an extension? It's more like an abstract class - how do they do it? So, I want to do this:

public interface IGetNews
void SomeNews(string s);

and then I can add
to any MonoBehavior, and thus "send news" to those items at any time.

I'm completely familiar with the various alternate solutions, but I want to do what Unity does magically with that form. What's the deal?

(BTW: I feel Unity should not have called these interfaces, since, it's basically nothing at all like an interface - it's sort of the opposite!. You could say they magically made a way to inherit from more than one abstract class, I guess.)


just for clarity if you've not used Unity before, the conventional way to do this (ie, since we don't have access to Unity magic) is like this: just add a UnityEvent to your daemon which will be sending the message in question:

public class BlahDaemon:MonoBehaviour
public UnityEvent onBlah;


Say you have classes Aaa, Bbb, Ccc which want to get the message. If you are new to UnityEvent, often you just "drag in the editor" from Aaa, Bbb, Ccc to the event in BlahDaemon. However you can "register" in code:

public class Aaa:MonoBehaviour
void Awake()
BlahDaemon b = Object.FindObjectOfType<BlahDaemon>();

public void OnBlah()
Debug.Log("almost as good as Unity's");

This is "almost as good" as using Unity's internal magic, although much more messy in code. Since you are "registering" so to speak in
, you are indeed piggybacking on the same magic Unity use.

Answer Source

When it comes to XXXUpdate, OnCollisionXXX and other MonoBehaviours, the way Unity registers is not reflection as it has been widely believed but some internal compilation process.


No, Unity doesn’t use System.Reflection to find a magic method every time it needs to call one.

Instead, the first time a MonoBehaviour of a given type is accessed the underlying script is inspected through scripting runtime (either Mono or IL2CPP) whether it has any magic methods defined and this information is cached. If a MonoBehaviour has a specific method it is added to a proper list, for example if a script has Update method defined it is added to a list of scripts which need to be updated every frame.

During the game Unity just iterates through these lists and executes methods from it — that simple. Also, this is why it doesn’t matter if your Update method is public or private.

In the case of an interface, I would assume it does a bit more since the interface is required. Else, you would just add the method like any other MonoBehaviour methods.

My assumption (that could be wrong), it uses a basic GetComponents on this GameObject. Then iterate the resulting array and call the method that HAS TO BE implemented since it is from the interface.

You could reproduce the pattern with:

NewsData data;
if(GetNews(out data))
    IGetNews [] getNews = data.gameObject.GetComponents<IGetNews>();
    foreach(IGetNews ign in getNews){ ign.SomeNews(); }

GetNews is a method that checks if some news should be sent to the object. You could think of it like Physics.Raycast that assigns values to a RaycastHit. Here it fills a data reference if that object is meant to receive news for any valid reasons.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download