当前位置: 首页 > 编程语言 > C#

在Unity中,Unity是如何神奇地调用所有“接口”的?分享

时间:2023-04-10 18:53:49 C#

在Unity中,Unity是如何神奇地调用所有“接口”的?Unity有一个“接口”,他们称之为IPointerDownHandler(doco)。你只需实施OnPointerDown...Unity将在任何此类MonoBehaviour中“神奇地”调用OnPointerDown。您无需注册、设置事件或执行任何其他操作。您所要做的就是将“IPointerDownHandler”和“publicvoidOnPointerDown”添加到您的类中,您可以随时神奇地获得这些消息。(如果您不是Unity开发人员-如果您在游戏运行时突然在编辑器中添加一个,它甚至可以工作!)他们究竟是如何做到的?我怎样才能用扩展来做到这一点?它更像是一个抽象类——他们是怎么做到的?所以,我想这样做:publicinterfaceIGetNews{voidSomeNews(strings);然后我可以将SomeNews添加到任何MonoBehavior,从而随时“向这些项目发送新闻”。我完全熟悉各种替代解决方案。我想知道他们是如何实现这种“神奇”行为的。(顺便说一句:我觉得Unity不应该调用这些接口,因为它基本上一点也不像接口——恰恰相反!我想你可以说他们神奇地想要从多个抽象类继承。)侧面:为了清楚起见,如果您以前没有使用过Unity,传统方法(即,因为我们无法访问Unity魔法)是这样的:只需将UnityEvent添加到您的守护程序,它就会发送Messagetitle:publicclassBlahDaemon:MonoBehaviour{publicUnityEventonBlah;...onBlah.Invoke();假设您有Aaa、Bbb、Ccc等类,并且想要获取这些消息。如果您是UnityEvent的新手,通常只需将“编辑器”从Aaa、Bbb、Ccc拖到BlahDaemon的Activity中即可。但是您可以在代码中“注册”:publicclassAaa:MonoBehaviour{voidAwake(){BlahDaemonb=Object.FindObjectOfType();b.onBlah.AddListener(OnBlah);}publicvoidOnBlah(){Debug.Log(“几乎和Unity一样好”);这“几乎和Unity一样好”);这与使用Unity的内部魔法“几乎一样好”,尽管代码更混乱。由于您“注册”在Awake上发言,您确实在使用Unity的相同魔力。Unity注册XXXUpdate、OnCollisionXXX和其他MonoBehaviours的方式并不具有反射性,因为它被广泛认为是一些内部编译过程。HowtoUpdateHasBeenCalled不,Unity不会在每次需要调用时使用System.Reflection来查找魔术方法。相反,第一次访问给定类型的MonoBehaviour时,底层脚本将通过脚本运行时(Mono或IL2CPP)检查它是否定义了任何魔法方法,并且缓存此信息。如果MonoBehaviour有特定的方法,它会被添加到正确的列表中,例如,如果脚本定义了一个Update方法,它会被添加到每帧需要更新的脚本列表中。在游戏中,Unity只是遍历这些列表并从中执行方法——这很简单。此外,这就是为什么Update方法是公共的还是私有的并不重要。http://blogs.unity3d.com/2015/12/23/1k-update-calls/在接口的情况下,我认为它需要更多,因为需要接口。否则,您只需像添加任何其他MonoBehaviour方法一样添加该方法。我的假设(可能是错误的),它在这个游戏对象上使用了一个基本的GetComponents。然后迭代结果数组并调用必须实现的方法,因为它来自接口。您可以使用以下方式重现该模式:NewsData数据;if(GetNews(outdata)){IGetNews[]getNews=data.gameObject.GetComponents();foreach(IGetNews登录getNews){ign.SomeNews();}}GetNews是一种检查是否应将某些新闻发送到对象的方法。你可以把它想象成Physics.Raycast,它给RaycastHit赋值。如果对象出于任何正当理由接收新闻,它将填充数据引用。您可以使用反射获取实现特定接口的程序集中的所有类型,然后实例化这些类型并通过接口在这些实例上调用方法。以上就是C#学习教程:在Unity中,Unity是如何神奇地调用所有“接口”的?分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——vartypes=this.GetType().Assembly.GetTypes().Where(t=>t.GetInterfaces().Contains(typeof(IGetNews)));foreach(vartypeintypes){varinstance=(IGetNews)Activator.CreateInstance(type);instance.SomeNews("新闻");},如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: