Wie funktioniert das Entity-Component-System von Unity in der Praxis? [geschlossen]

7

Auf den ersten Blick scheint Entity-Component eine gute Möglichkeit zu sein, Spiele zu programmieren. Alles ist ein Spielobjekt und diese Spielobjekte bestehen aus Komponenten. Die Attraktion ist, dass Komponenten sehr flexibel sind und Sie sie lediglich einem Spielobjekt "hinzufügen" müssen, um dessen Funktionalität zu erben.

Ein gutes Beispiel könnte also eine Plattform sein, auf die der Charakter springen muss. Vielleicht hat dieses Ding einen Collider, eine sich bewegende Komponente, vielleicht eine rotierende Komponente oder vielleicht sogar eine starre "RotatingAndMovingPlatformComponent". Okay, das klingt großartig. Fügen Sie einfach alle diese Komponenten zum Spielobjekt hinzu und fertig, Sie haben diese zusätzliche Funktionalität. Ich finde jedoch, dass diese Komplexität dort endet, wo ihre Nützlichkeit endet.

Versuchen Sie dies mit Menüs, komplexen Charakterbewegungen mit mehreren Zuständen, abstrakten Ideen wie Spielmodi oder Spielzuständen, und Ihre Flexibilität und Modularität werden zerstört. Menüs beinhalten viele Besonderheiten, komplexe Zeichenbewegungen beinhalten oft viele Zustände, was bedeutet, dass entweder eine Kommunikation zwischen diesen Komponenten erforderlich ist oder dass eine Steuerungskomponente nur für diesen Charaktertyp erstellt werden muss. Darüber hinaus müssen sich einige Komponenten in irgendeiner Weise auf den Spielstatus verlassen.

Ich sehe sehr wenig Nutzen darin, auf diese Weise gegenüber gewöhnlicher Vererbung zu programmieren. Das Fehlen von Objektstrukturen zur Kompilierungszeit macht es sehr schwierig und unzuverlässig, viele Dinge zu tun.

Ich bin der Meinung, dass die beste und einfachste Vorgehensweise darin besteht, größere Komponenten mit mehr Abhängigkeiten zu verwenden. Ich sehe dies nicht als Problem (eher wie die Architektur von unreal 4), aber dann frage ich mich, wozu die Entity-Component-Architektur gut ist.

Ben
quelle
1
Der Titel scheint zu fragen: "Wie funktioniert es?", Aber der Körper liest sich eher wie ein Scherz oder fragt, warum er verwendet werden sollte.
Anko
2
Wie wird dies als "Meinungsbasiert" geschlossen? Es gibt nur einen Weg, wie Unity funktioniert, der Typ fragt nach dieser Antwort. Es gibt nur eine Antwort, und es ist mit Sicherheit keine Meinung.
Verwirrt

Antworten:

8

Ich werde eine fast meinungsbasierte Antwort riskieren und veröffentlichen. Was Unity fehlt, ist das entfaltete "System" -Element. Es wäre viel schöner, "Component-Entity-System" anstelle des aktuellen "Component-Entity" zu haben. Das liegt an den von Ihnen erwähnten Problemen.

Das von Ihnen erwähnte Kommunikationsproblem kann durch Hinzufügen von System gelöst werden. Die Unity-Komponente enthält sowohl Daten als auch Logik. Sie können also entweder eine massive Komponente erstellen, die eine Menge Dinge erledigt und viel weiß. Diese Art von Monolith kann in einem anderen Spiel fallen gelassen werden, aber Sie können einen Teil davon wiederverwenden. Sie können auch versuchen, es zu brechen, indem Sie viele kleine Komponenten erstellen, aber Sie werden am Ende Tonnen winziger Komponenten haben, die Ereignisse, Nachrichten und andere Dinge austauschen. Sie können sie "wiederverwenden", aber sie funktionieren nicht alleine.

Hier kommt das System ins Spiel. Das System ist nur eine Logik. Es wird Ihrem Spielmanager sagen "Ich kann Ihren Baum zum Fliegen bringen, aber ich brauche einen Baum, um [Flügel, Physik] zu haben". Der Spielmanager sucht dann nach Entitäten mit Flügeln und Physik und gibt sie dem System. Das System wird dann alles tun, um Ihren Baum zum Fliegen zu bringen. Flügel und Physik sind Komponenten. Aber anders als bei Unity werden sie nur Daten enthalten, z. B. wie breit die Flügel sind oder wie schnell Objekte fallen (es ist ein fliegender Baum, es wird schnell fallen!). Jetzt können alle Ihre Komponenten wiederverwendet werden, da sie nichts anderes als einige seltsame Daten kennen, die sie enthalten. Sie haben keine Bedeutung, es sei denn, ein System ist interessiert. Es ist jedoch eine Systemaufgabe, die Daten zu lesen und zu verwenden. Das System muss nicht wissen, wer welche Komponente hat, und muss nicht über andere Systeme Bescheid wissen.

Wie kann man es nun in Unity übersetzen? Sie können Ihren benutzerdefinierten Manager schreiben, in dem Komponenten Systeme sind, und alles, was sie tun, ist Logik (und Systemzustände, falls erforderlich, wie im Menüsystem möchten Sie möglicherweise kurz wissen, auf welche Schaltfläche zuletzt geklickt wurde). Ihr GameObject ist Ihre Entität. Was ist mit Models? Nun, Sie verwenden C # oder JavaScript. Verwenden Sie dazu einfach die normale Klasse / das normale Objekt. Deshalb benötigen Sie einen benutzerdefinierten Manager. Umgang mit Nicht-Einheitsmodellen.

Die zweite Möglichkeit besteht darin, Komponenten in Modelle und Systeme aufzuteilen. Die Komponente kann GameObject und die gesamte Szene mit anderen Komponenten nach anderen GameObjects abfragen. Legen Sie ein GameObject als Systemmanager fest. Dieser GO enthält nur Komponenten, die Dinge tun können. Andere Entitäten in der Szene haben Komponenten mit reinen Daten.

Bitte beachten Sie, dass dies nur eine Theorie (zum Hinzufügen von Systemen zu Unity) ist und möglicherweise nicht zu einer effektiven Architektur für Ihr Spiel führt.

Über die Vererbung. Der einfachste Weg, den Unterschied zu erkennen, besteht darin, beide Muster zur Beschreibung des Objekts zu verwenden. Beschreiben wir "Auto" in der Standardklassenhierarchie. Das Auto wird von den Rädern geerbt, damit es sich bewegen kann. Das Auto ist also ein Rad. Jetzt in der Komponentenentität. Dieses Objekt hat Räder und Türen, also ist es ein Auto!

Nur wenige Links zu Artikeln über Component-Entity. Erstens beschreibt man Unity wie Component-Entity, zweitens fügt man Systeme hinzu.

http://gameprogrammingpatterns.com/component.html

http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/

http://python-utilities.readthedocs.org/en/latest/ebs.html

Polan
quelle
Ich mochte die Idee nicht, dass "Auto ein Rad ist", aber die Gesamtidee ist ziemlich nett. Normalerweise wickle ich meine Logik in die Komponenten selbst ein.
MVCDS
5

Dies beantwortet die Frage nicht direkt, aber nach den Geräuschen scheinen sich Ihre Frage und die gewünschten Informationen ein wenig zu unterscheiden (zumindest für mich). Dieser "Ausblick" könnte also helfen, sie zu verbinden.

Abstraktionen führen häufig zu Verallgemeinerungen, sodass Sie sich auf zukünftige Unbekannte vorbereiten können. Dies ist, was Unity tut, da es kaum etwas über die Art des Spiels weiß, das Sie machen werden, bis Sie anfangen, diese Informationen (dh Spielcode) bereitzustellen. Je komplexer Ihre Abstraktionen (höchstwahrscheinlich) sind, desto allgemeiner sind sie.

Generalisierung ist eine großartige Sache. Sie ermöglicht es Ihnen, Code zwischen Spielen wiederzuverwenden (mit wenig bis gar keinen Änderungen) und Anpassungen vorzunehmen, wenn sich Designdetails ändern. Mit der Verallgemeinerung kommt jedoch das lange erzählte Sprichwort: Zu viel von irgendetwas ist eine schlechte Sache . Eine Überverallgemeinerung kann zu schwierigen und langwierigen Implementierungen führen, um etwas Einfaches zu tun.

Ein Beispiel:

Angenommen, Sie sind eine Spieleentwicklungsfirma. Sie mögen TBS-Spiele und planen, immer nur TBS-Spiele zu machen. Wäre es sinnvoll, Ihr Game-State-Management-System so zu entwerfen und zu programmieren, dass es das zukünftige Potenzial von RTS-Spielen verallgemeinert, wenn Sie wissen, dass Sie immer nur TBS-Spiele entwickeln werden? Nein, Sie können diese Brücke nicht überqueren, wenn sie kommt.

Verwechseln Sie jetzt nicht die Überverallgemeinerung mit "Nicht verallgemeinern", da wir dadurch einiges an Flexibilität gewinnen. Sie wissen vielleicht genau, was dieses Spiel, das Sie machen, zu 100% benötigt (wahrscheinlich nicht und sie werden sich ändern), aber um des Arguments willen können Sie so tun, als ob Sie es tun. Weißt du, was das nächste TBS-Spiel braucht? Nein, es besteht die Möglichkeit, dass es in irgendeiner Weise mechanisch anders sein wird (damit sich die Leute nicht langweilen, bevor Sie es schaffen). Sie brauchen also noch eine gewisse Verallgemeinerung und Abstraktion, nur nicht in dem Maße, wie es die Einheit tut, da Sie mehr wissen.

TLDR;

Zu viel und zu wenig Verallgemeinerung kann eine schlechte Sache sein (für Anfänger und Entwickler von Einzelspielen ist es viel besser, zu wenig zu verallgemeinern). Je mehr Sie wissen, desto weniger müssen Sie verallgemeinern.

Shelby115
quelle