在统一,如何统一神奇调用所有的接口? [英] In Unity, how does Unity magically call all Interfaces?

查看:125
本文介绍了在统一,如何统一神奇调用所有的接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

统一有一个接口 IPointerDownHandler DOCO ),这是不够公平。

Unity have an interface IPointerDownHandler (doco), which is fair enough.

对于一个你必须实现的 OnPointerDown

For that one you have to implement OnPointerDown

且说你有任何数量的MonoBehaviour的...

Say you then have any number of MonoBehaviour with ...

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



在一个场景。

in a scene.

事实上,团结不叫 OnPointerDown 在所有这些,当相关的事情发生

您不一定要注册它们,设置事件,或任何东西。你要做的就是添加,IPointerDownHandler和公共无效OnPointerDown的一类,你可以得到在任何时候都奇迹般地这些消息。

You do NOT have to register them, set an event, or anything. 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, note too that it even works if you suddenly add one of these at run time, during a game. So, once the scene is already running, Instantiate a new GameObject, and add a component such as Whoa above - it will work from that frame onwards!

怎么他们会怎么做呢?怎样才能的我这样做的具有扩展?它更像是一个抽象类,他们是怎么做到这一点。

How the hell do they do that? How can I do that with an extension? It's more like an abstract class, how'd they do it?

我想这样做:

public interface IGetNews
 {
 void SomeNews(string s);
 }



然后我可以添加 SomeNews 来的旧MonoBehavior(说20在我的场景),基本上发送消息到所有20个项目的任何时间。

and then I can add SomeNews to any old MonoBehavior (say 20 in my scene), and basically send news to all 20 items any time.

请,我完全熟悉各种替代解决方案,该用例,但我想做什么神奇的团结做。这是怎么回事???是否有某种方式来做到这一点在C#中,我消隐?

Please, I'm totally familiar with the various alternate solutions to that use case, but I want to do what Unity magically do. What's the deal??? Is there some way to do this in c# I am blanking on?

这是有趣的一点是,我觉得团结应该的没有称这些接口因为,它基本上类似的界面什么 - 这有点相反的。 (你可以说,他们奇迹般地做了一个方法,从多个抽象类继承,我想 - 但它ECS不是OO)

An interesting point is, I feel Unity should not have called these interfaces, since, it's basically nothing 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 -- but then it's ECS not OO.)

旁白:

在通过纯粹的,海事组织最好的解决方法是:在你的后台程序......

purely by the by, IMO the best workaround is: in your daemon...

public class BlahDaemon:MonoBehaviour
  {
  public UnityEvent onBlah;

    ...
    onBlah.Invoke();



你的类其想要得到的单位人造接口的 - 像消息

public class BoringClass:MonoBehaviour
  {
  void Awake()
    {
    BlahDaemon b = Object.FindObjectOfType<BlahDaemon>();
    b.onBlah.AddListener(OnBlah);
    }

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



因为(我) UnityEvent 是完美的,美丽的(最好的东西统一做过其他比新IAP系统); (二)你基本上是在醒注册,所以你确实巧妙地援用相同的魔法统一使用自己;你捎带上了。

Since (i) UnityEvent is Perfect and Beautiful (the best thing Unity have ever done other than the new IAP system); (ii) you are essentially "registering" in Awake, so you are indeed cleverly availing yourself of the same magic Unity use; you are piggybacking on it.

推荐答案

在谈到XXXUpdate,OnCollisionXXX等MonoBehaviours,统一登记的方式并不反思它已被广泛认为但一些内部的编译过程。

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.

否,统一不使用的System.Reflection每次需要调用一次找到一个魔术方法。

相反,第一次给定类型的MonoBehaviour访问底层脚本通过脚本运行时(无论是
单声道或IL2CPP)是否有定义的任何神奇的方法,这
信息缓存检查。如果一个MonoBehaviour具有特定方法是
加入到一个适当的列表中,例如,如果一个脚本有更新方法
中定义它被添加到需要更新
每一个脚本列表。帧

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-电话/

在接口的情况下,我会假设,因为需要对接口确实有点多。否则,你想补充像任何其他MonoBehaviour方法的方法。

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.

我的假设(即可能是错的),它在这个游戏物体使用基本GetComponents。然后遍历结果数组并调用一个必须实现的,因为它是从接口中的方法

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.

您可以复制的模式:

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



GetNews是,检查是否有消息要被发送到物体的方法。你可以把它像Physics.Raycast将值赋给一个RaycastHit。这填补了一个数据引用,如果该对象是为了获得新闻任何正当理由。

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.

这篇关于在统一,如何统一神奇调用所有的接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆