2015-05-13 30 views
5

Sono abbastanza nuovo in C#, proveniente da un forte background in Java, Python e alcuni elementi "web". Quindi probabilmente mi manca un po 'di conoscenza qui, che spero che qualcuno possa riempire per me.In Unity cosa sta succedendo esattamente quando implemento Update() e altri messaggi da MonoBehaviour

Passando attraverso l'API Unity Scripting, ho notato molti metodi, elencati sotto "Messaggi", che è il mio primo punto di confusione. Qual è esattamente la differenza tra un "Messaggio" e un "Metodo", per me sembrano come se fossero la stessa cosa, ma la terminologia mi sta buttando fuori.

Il mio secondo punto di confusione è che quando implemento un "Messaggio" come Update() nelle mie classi derivate, non devo usare la parola chiave override. Il che mi turba, perché non lo nasconderei? In tal caso, il ciclo di aggiornamento non dovrebbe conoscere solo MonoBehaviour e non la mia classe derivata e chiamare Update() in MonoBehaviour, invece della mia classe? Questo mi sta lanciando per un ciclo. Mi diverte che questo accada dietro le quinte?

Sono andato molto d'accordo con Unity e C#, questo è solo un punto critico per me, dove mi sento come se mi mancasse qualche conoscenza.

risposta

7

Una cosa da ricordare è che il team Unity non ha necessariamente progettato le proprie API di scripting (inclusa la classe MonoBehaviour) per promuovere buoni principi di sviluppo del software; l'hanno progettato per accessibilità e facilità d'uso (specialmente per i non programmatori). Questo sta lentamente cambiando, ma c'è ancora molta inerzia verso "ciò che è facile" invece di "ciò che è giusto".

Detto questo, rispondiamo alla tua domanda. Per quanto riguarda "i messaggi," verificare che cosa i documenti dicono di Component.SendMessage:

chiama il metodo di nome methodName su ogni MonoBehaviour in questo oggetto gioco.

Quando si guarda la documentazione per, diciamo, Collider e vedere dei metodi elencati nella sezione Messaggi, questa è un'indicazione che se si implementa questi metodi, perché saranno chiamati (tramite SendMessage) in risposta a qualche evento o azione (OnCollisionEnter, ad esempio, "viene chiamato quando questo collider/corpo rigido ha iniziato a toccare un altro corpo rigido/collisore."). Potrei averli implementati come delegati di eventi, ma il team Unity ha scelto di implementare il proprio sistema di messaggistica usando stringhe, ancora una volta, nel nome della "facilità d'uso".

Per lo stesso effetto, se si cammina lungo la catena di ereditarietà per una classe MonoBehaviour, si noterà che in nessuna parte della catena si fa effettivamente trovare metodi dichiarati nome Update o Start o gli altri eventi del ciclo di vita dei propri script. Unity tratta questi come metodi magici e li chiama (sempre tramite SendMessage, appare) se esistono nella classe di implementazione. Ecco perché non importa se il tuo metodo Update è pubblico o protetto o privato ... verrà comunque chiamato.

+0

Questo chiarisce bene le cose. Grazie. –

+0

SendMessage() usa la riflessione. Update() non usa SendMessage() - Vedi la sezione "Come si chiama l'aggiornamento" in blogs.unity3d.com/2015/12/23/1k-update-calls – BlueSilver

2

Il modo in cui lo stanno facendo sotto il cofano è quello di utilizzare la riflessione per ottenere il metodo che corrisponde, ed è per questo

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

non andranno chiamato e

void Update() {} 

sarà

Cercano un metodo che corrisponda al nome e alla firma dei parametri (in questo caso non accetta un argomento).I primi due hanno un problema con l'introduzione di maiuscole o parametri.

Utilizzando la riflessione non è necessario avere una funzione pubblica per chiamarla ma non danneggiarla se lo è.

Utilizzano lo stesso tipo di cosa per il sistema di messaggi, motivo per cui è possibile chiamare qualsiasi funzione, sebbene limitino a prendere solo una variabile con il messaggio.