Bevor wir uns mit dem befassen, was ein Ereignissystem ist und wie es erstellt wird, lassen Sie uns zunächst besprechen, warum es nützlich ist, ein Ereignissystem zu haben?
In Unity verlassen Sie sich auf eines der beiden unten aufgeführten Dinge, um die Daten oder Abhängigkeiten aus einer anderen Klasse abzurufen.
Sie haben entweder
Ihre öffentlichen oder serialisierten Eigenschaften in einem Monobehaviour , um sie vom Inspektor zuweisen zu können, um die Referenzen abzurufen.
Oder
Verwenden Sie das Singleton-Muster in Ihrem Code, um die benötigten Daten abzurufen.
Wenn Sie das Singletons-Entwurfsmuster noch nicht kennen, handelt es sich um ein Software-Entwurfsmuster, das die Instanziierung einer Klasse auf eine einzelne Instanz beschränkt. Dies ist nützlich, wenn genau ein Objekt benötigt wird, um Aktionen im gesamten System zu koordinieren.
Wenn ein anderes Objekt im Code Daten von diesem Objekt benötigt, rufen wir die Singleton-Instanz auf, um darauf zu verweisen. Singletons sind sehr nützlich, um auf die Klassen zu verweisen, von denen Sie wissen, dass sie nur eine Instanz davon benötigen.
Unabhängig davon, welchen Ansatz Sie zum Abrufen der Abhängigkeiten verwenden, treten Probleme auf, wenn Sie eine kleine Sache optimieren oder den Code umgestalten, insbesondere wenn Sie an einem sehr großen Projekt arbeiten.
Lassen Sie uns die Abhängigkeiten lindern!
Ereignissysteme helfen bei der Modularisierung Ihres Codes, indem sie Nachrichten zwischen Klassen senden, die sich nicht direkt kennen. Sie ermöglichen es, auf eine Änderung eines Zustands zu reagieren, ohne ihn ständig in einer Aktualisierungsschleife zu überwachen. Es ist eine Form des Beobachtermusters, in dem ein Objekt, das als Subjekt bezeichnet wird, eine Liste seiner abhängigen Objekte, die als Beobachter bezeichnet werden, verwaltet und sie automatisch über Zustandsänderungen benachrichtigt, normalerweise durch Aufrufen ihrer Methoden.
Lassen Sie uns dies am Beispiel eines Zeitschriftenabonnements verstehen.
- Ein Zeitschriftenverlag(Betreff) ist im Geschäft und veröffentlicht Zeitschriften (Daten).
- Wenn Sie (Benutzer von Daten / Beobachter) an der Zeitschrift interessiert sind, die Sie abonnieren(registrieren), und wenn eine neue Ausgabe veröffentlicht wird, wird diese an Sie geliefert.
- Wenn Sie sich abmelden (abmelden), erhalten Sie keine neuen Ausgaben mehr.
- Der Verlag weiß nicht, wer Sie sind und wie Sie das Magazin verwenden, er liefert es Ihnen nur, weil Sie Abonnent sind (lose Kopplung).
Wie gestaltet man das Event-System?
Ich habe eine Szene, in der wir einen ThirdPersonController-Player (sagen wir Mr. X), ein Labyrinth und einige Türen haben. Sagen wir Mr. X will den Ausgang des Labyrinths erreichen, aber es gibt einige Türen dazwischen, die geöffnet werden können, sobald Mr. X sich ihnen nähert.
Die Türen haben Trigger Box Collider, der den anderen an dieser Kollision beteiligten Collider auslöst.
Lassen Sie uns dies mit einem Ereignissystem implementieren.
Beginnen wir mit dem Hinzufügen eines GameObject in der Szene und dem Hinzufügen eines neuen Skripts namens EventsManager.cs
Unsere ersten Ereignisse werden diejenigen sein, die ausgelöst werden, wenn unser Spieler den Triggerbereich der Tür betritt oder verlässt.
Dafür Im EventsManager .cs-Klasse, Erstellen Sie zwei Ereignisaktionen DoorTriggerEnter und DoorTriggerExit, auch, Methoden, die die jeweilige Ereignisaktion aufrufen können. Erstellen Sie außerdem eine statische Singleton-Referenz für die Klasse.
Jetzt brauchen wir Objekte, die diese Ereignisse auslösen und abonnieren können. Erstellen Sie dazu zwei Klassen, eine für die Tür, DoorController .cs, und eine für den Triggerbereich der Tür, DoorTrigger.cs.
Im DoorController.erstellen Sie stattdessen zwei Methoden, die DoorTriggerEnter , wenn jemand DoorTriggerEnter- oder DoorTriggerExit-Ereignisse auslöst, und führen Sie ihre Aufgaben aus. Greifen Sie in der Start-Methode des Doorcontrollers mithilfe der statischen Instanz auf die Ereignisse aus der EventsManager-Klasse zu und abonnieren Sie die entsprechende Methode.
Jetzt sind unsere Veranstaltungen fertig und Abonnenten hören sich diese Veranstaltungen an. In der Ontrigger Klasse müssen wir diese Ereignisse nur in der OnTriggerEnter Methode OnTriggerEnter .
Ok.. fügen wir also DoorController- und DoorTrigger-Skript an jede Tür bzw. jeden Triggerbereich an und spielen die Szene ab.
Ohhh! Es gibt ein Problem…
Unser EventManager ist eine Singleton-Klasse, und jeder Türauslöser ruft das Ereignis auf, und jeder Türcontroller hört auf dasselbe Ereignis und reagiert darauf. Wir müssen beim Aufrufen des Ereignisses eine eindeutige ID übergeben, damit nur die Tür mit derselben ID dieses Ereignis abhört.
In unserem speziellen Fall sind Trigger und das übergeordnete Objekt der Tür identisch. Wir können also die Instanz-ID des gameobject des übergeordneten gameobject .
Lass uns die Szene spielen..
Yeahhh.. es funktioniert jetzt wie erwartet.
Stellen Sie sicher, dass Sie diese Ereignisse abbestellen, da sie zu unerwünschten Fehlern führen können. Zum Beispiel, wenn Sie Ihre Tür zur Laufzeit zerstören usw.
So können wir unser einfaches Ereignissystem erstellen.
Das ist alles für jetzt Leute… Glückliche Codierung! 🙂