Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Unity中,当我实现Update()和来自MonoBehavior的其他消息时,到底发生了什么_C#_Unity3d_Game Engine - Fatal编程技术网

C# 在Unity中,当我实现Update()和来自MonoBehavior的其他消息时,到底发生了什么

C# 在Unity中,当我实现Update()和来自MonoBehavior的其他消息时,到底发生了什么,c#,unity3d,game-engine,C#,Unity3d,Game Engine,我对C#相当陌生,有Java、python和一些“web”方面的深厚背景。所以我可能只是缺少一些知识,希望有人能代替我 在浏览Unity脚本API时,我注意到了许多方法,它们列在“消息”下面,这是我的第一个困惑点。“信息”和“方法”之间到底有什么区别?在我看来,它们似乎是同一件事,但术语让我感到不舒服 我的第二个困惑点是,当我在派生类中实现类似Update()的“消息”时,我不必使用override关键字。这让我心烦,因为我不该把它藏起来吗?在这种情况下,更新循环不是只知道MonoBehavio

我对C#相当陌生,有Java、python和一些“web”方面的深厚背景。所以我可能只是缺少一些知识,希望有人能代替我

在浏览Unity脚本API时,我注意到了许多方法,它们列在“消息”下面,这是我的第一个困惑点。“信息”和“方法”之间到底有什么区别?在我看来,它们似乎是同一件事,但术语让我感到不舒服

我的第二个困惑点是,当我在派生类中实现类似Update()的“消息”时,我不必使用override关键字。这让我心烦,因为我不该把它藏起来吗?在这种情况下,更新循环不是只知道MonoBehavior而不是我的派生类,并在MonoBehavior中调用update(),而不是我的类吗?这真是让我大吃一惊。我很有趣这是幕后发生的事吗


我与Unity和C#相处得很好,这只是我的一个症结所在,我觉得我缺少一些知识。

需要记住的一点是,Unity团队不一定设计他们的脚本API(包括MonoBehavior类)来促进良好的软件开发原则;他们设计它是为了便于访问和使用(特别是对于非程序员)。这一点正在慢慢改变,但对于“什么是容易的”而不是“什么是正确的”仍然有很大的惯性

也就是说,让我们开始回答你的问题。关于“消息”,请查看文档中的内容:

在此游戏对象中的每个MonoBehavior上调用名为methodName的方法

例如,当您查看文档并看到Messages部分下列出的方法时,这表明如果您实现这些方法,它们将被调用(通过SendMessage)以响应某些事件或操作(例如OnCollisionCenter,“当这个碰撞器/刚体开始接触另一个刚体/碰撞器时调用。”)。我可能会将它们作为事件代理来实现,但Unity团队还是选择使用字符串来实现他们自己的消息传递系统,这也是以“易用性”的名义实现的


出于同样的效果,如果您沿着MonoBehavior类的继承链走,您会注意到在该链中没有找到名为
Update
Start
的声明方法或脚本的其他生命周期事件。Unity将这些视为神奇的方法并调用它们(再次通过SendMessage显示)如果它们存在于实现类中。这就是为什么无论你的
更新
方法是公共的还是受保护的,甚至是私有的……它仍然会被调用。

他们在幕后做这件事的方式是使用反射来获得匹配的方法,这就是为什么

 void update(){}
 void Update(bool inVariable){}
不会有人打电话

void Update() {}
意志

他们寻找同时匹配名称和参数签名的方法(在本例中不接受参数)。前两种方法在大写或参数输入方面存在问题

通过使用反射,你不需要让一个函数成为公共函数来调用它,但如果它是公共函数,也不会对它造成伤害

它们在消息系统中使用相同的类型,这就是为什么您可以调用任何函数,尽管它们限制为只在消息中使用一个变量。

SendMessage()使用反射。Update()不使用SendMessage()-请参阅blogs.unity3d.com/2015/12/23/1k-Update-calls中的“如何调用更新”一节