2015-05-13 9 views
5

Ich bin ziemlich neu in C#, aus einem starken Hintergrund in Java, Python und einige "Web" Zeug. Ich verpasse hier wohl nur ein wenig Wissen, dass hoffentlich jemand für mich ausfüllen kann.In Unity, was genau passiert, wenn ich Update() implementieren, und andere Nachrichten von MonoBehaviour

Als ich die Unity Scripting API durchging, bemerkte ich viele Methoden, die unter "Nachrichten" aufgelistet sind, was meine erste Verwirrung ist. Was genau ist der Unterschied zwischen einer "Botschaft" und einer "Methode", für mich scheinen sie das Gleiche zu sein, aber die Terminologie wirft mich aus.

Mein zweiter Punkt der Verwirrung ist, dass, wenn ich eine "Nachricht" wie Update() in meinen abgeleiteten Klassen implementieren, muss ich nicht das override-Schlüsselwort verwenden. Was nervt mich, denn würde ich es nicht einfach verstecken? In diesem Fall würde die Update-Schleife nicht nur über MonoBehaviour und nicht über meine abgeleitete Klasse wissen, und in MonoBehaviour Update() anstelle meiner Klasse aufrufen? Das wirft mich für eine Schleife. Ich bin amüsant, dass hinter den Kulissen etwas passiert?

Ich komme wirklich gut mit Unity aus, und C#, das ist nur ein Knackpunkt für mich, wo ich fühle, dass mir etwas Wissen fehlt.

Antwort

7

Eine Sache zu erinnern ist, dass das Unity-Team nicht unbedingt ihre Skript-API (einschließlich der MonoBehaviour-Klasse) entworfen hat, um gute Software-Entwicklungsprinzipien zu fördern; sie haben es für die Zugänglichkeit und Benutzerfreundlichkeit entworfen (besonders für Nicht-Programmierer). Das ändert sich langsam, aber es gibt immer noch eine gewisse Trägheit gegenüber "Was ist leicht" anstatt "Was ist richtig".

Wie gesagt, lassen Sie uns Ihre Frage beantworten. In Bezug auf Check-out „Nachrichten“, was die docs sagen über Component.SendMessage:

die auf jedem MonoBehaviour genannt Anrufe Methode methoden in diesem Spiel-Objekt.

Wenn Sie in der Dokumentation suchen, sagen wir, Collider und die Methoden unter dem Abschnitt Nachrichten aufgeführt wird, ist das ein Hinweis darauf, dass, wenn Sie diese Methoden implementieren, werden sie (via Sendmessage) als Reaktion auf ein Ereignis aufgerufen werden oder Aktion (OnCollisionEnter, zum Beispiel "wird aufgerufen, wenn dieser Collider/Starrkörper einen anderen Starrkörper/Collider berührt hat."). Ich habe sie möglicherweise als Event-Delegaten implementiert, aber das Unity-Team entschied sich, sein eigenes Messaging-System unter Verwendung von Strings zu implementieren, wiederum unter dem Namen "Benutzerfreundlichkeit".

Zu diesem gleichen Effekt, wenn Sie die Vererbungskette für eine MonoBehaviour Klasse gehen, werden Sie, dass nirgendwo in der Kette bemerken finden Sie tatsächlich deklarierten Methoden Update oder Start oder die anderen Ereignisse im Lebenszyklus Ihrer Skripte genannt. Unity behandelt diese als magische Methoden und ruft sie (wiederum über SendMessage) auf, wenn sie in der implementierenden Klasse existieren. Deshalb ist es egal, ob Ihre Update Methode öffentlich oder geschützt oder sogar privat ist ... sie wird trotzdem aufgerufen.

+0

Das klärt die Dinge schön auf. Vielen Dank. –

+0

SendMessage() verwendet Reflektion. Update() verwendet nicht SendMessage() - Siehe Abschnitt "Wie das Update aufgerufen wird" in blogs.unity3d.com/2015/12/23/1k-update-calls – BlueSilver

2

Die Art, wie sie es unter der Haube tun, ist durch die Reflexion mit der Methode zu erhalten, die übereinstimmt, weshalb

void update(){} 
void Update(bool inVariable){} 

wird nicht aufgerufen und

void Update() {} 

wird

Sie suchen nach einer Methode, die sowohl die Namen- als auch die Parametersignatur abbildet (in diesem Fall wird kein Argument berücksichtigt).Die ersten beiden haben ein Problem mit Großschreibung oder Parametereingabe.

Durch die Verwendung von Reflektion muss eine Funktion nicht öffentlich sein, um sie aufzurufen, aber es tut nicht weh, wenn sie es ist.

Sie verwenden die gleiche Art für das Nachrichtensystem, weshalb Sie jede Funktion aufrufen können, obwohl sie sich darauf beschränken, nur eine Variable mit der Nachricht aufzunehmen.