Unity has an "interface":
IPointerDownHandler
(doco)
You simply implement OnPointerDown ...
public class Whoa:MonoBehaviour,IPointerDownHandler { public void OnPointerDown (PointerEventData data) { Debug.Log("whoa!"); } }
and Unity will "magically" call the OnPointerDown
in any such MonoBehavior.
You do NOT have to register them, set an event, nor do anything else.
All you do syntactically is add "IPointerDownHandler" and "public void OnPointerDown" to a class, and you can get those messages magically.
(If you're not a Unity dev - it even works if you suddenly add one in the Editor while the game is running!)
So, I want to do this:
public interface IGetNews { void SomeNews(string s); }
and then I can add SomeNews
to any MonoBehavior.
(BTW: I feel they 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.)
Aside:
if you've not used Unity before, the conventional way to do this - since we don't have access to Unity magic - is just add a UnityEvent to your daemon which will be sending the message in question:
public class BlahDaemon:MonoBehaviour { public UnityEvent onBlah; ... onBlah.Invoke();
Say you have classes Aaa, Bbb, Ccc which want to get the message. Simply connect the Unity event (either by dragging in the editor or in code), example:
public class Aaa:MonoBehaviour { void Awake() { BlahDaemon b = Object.FindObjectOfType<BlahDaemon>(); b.onBlah.AddListener(OnBlah); } public void OnBlah() { Debug.Log("almost as good as Unity's"); } }
You're basically "registering" your call in Awake
, you are indeed piggybacking on the magic Unity use - whatever it is. But I want to use the magic directly.
Since Unity 2019.3 interface-type fields are serializable.
Implementing an Interface During the class declaration, after the class name, add a colon ':' followed by the interface name. The class must then implement every member declared in the interface, making them all public.
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.
HOW UPDATE IS CALLED
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.
http://blogs.unity3d.com/2015/12/23/1k-update-calls/
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With