Ich habe das Java Artemis Entity Component System gesehen und an das Entity System in Unity3D gedacht.
In Artemis können Sie beispielsweise jeder Entität nur einen Komponententyp hinzufügen, und die Logik befindet sich nicht in der Komponente.
In Unity3D ist das völlig anders. Kann mir jemand erklären, wie das Entitätssystem in Unity 3d funktioniert?
Ich meine, ist Unity3D ein echtes Entitätssystem oder ist es etwas anderes?
unity
3d
architecture
user2933016
quelle
quelle
Antworten:
Ja, es ist immer noch ein Entitätssystem. Es gibt keine strenge Definition für die Funktionsweise eines Entitätssystems. Es ist also in Ordnung, dass es sich von Artemis unterscheidet. Beide haben noch Entitäten, die aus Komponenten bestehen.
Das Ziel eines Entitätssystems besteht darin, sich von vererbungsbasierten Designs zu entfernen. Das System von Unity erreicht dieses Ziel.
Ähnlich wie bei Artemis können Sie einer Entität Komponenten hinzufügen, um ein neues Objekt zu erstellen. Durch Ändern der Daten in den Komponenten kann das erzeugte Objekt auf Oberflächenebene drastisch geändert werden. Einige wesentliche Unterschiede bestehen darin, wo die Logik gespeichert ist und wie Komponenten für die Verarbeitung gruppiert werden . Obwohl diese Unterschiede dramatisch erscheinen mögen, sind sie nicht zu unterschiedlich. Beide Ansätze können noch ähnlicher modifiziert werden. Sie können beispielsweise Komponenten mit nur Daten in Unity erstellen und ein "System" erstellen, das alle Spielobjekte mit bestimmten Komponenten findet und verarbeitet.
In jedem Fall werden Sie Komponenten und Entitäten haben. Wo die Entitäten nicht aus einer langen Liste geerbter Klassen abgeleitet sind. Dies reduziert die Codeduplizierung, reduziert unnötigen Code und unnötige Daten und gibt Ihnen eine einfache Möglichkeit, darüber nachzudenken, wie Objekte erstellt werden.
quelle
Unity3D funktioniert auf dem GameObject-Component-Modell. Es ist so viel anders als Entity Component Systems. Meiner Erfahrung nach ist es schlimmer, weil wenn Sie eine Logik codieren möchten, diese in die Skriptkomponente anstatt in die Systeme eingefügt wird. Wie unterschiedlich ist es vom OOP-Modell? Unity3D GameObject enthält Daten und Logik - genau wie in OOP können diese Komponenten nicht wiederverwendet werden (was einer der Gründe dafür ist, dass OOP nicht ausgeführt wird). Natürlich können Sie einige kugelsichere Konventionen treffen, die Sie davon abhalten, Daten und Logik zu mischen, aber es könnte eine ziemlich harte Arbeit sein, dies kontinuierlich zu tun.
Abhängigkeiten. Wenn Sie in ECS arbeiten, hat jedes System einen Aspekt (es wird beschrieben, welche Komponenten es verwaltet). Dank des Aspekts hängen Ihre Komponenten vom System und nicht von anderen Komponenten ab. Ich habe Code gesehen, in dem nur wenige Komponenten aufeinander verweisen. Wenn die Reihenfolge der Ausführung nicht richtig eingestellt war, dann ... totales Durcheinander. Wenn Sie Komponenten- (Logik-) Abhängigkeiten umgestalten, ist es besser, dies an EINER Stelle wie System zu tun, anstatt an wenigen Stellen (Komponenten).
Der weitere große Nachteil des in Unity3D verwendeten Modells ist das Problem der Verwaltung von Objekten desselben Aspekts (Satz von Komponenten). Meiner Meinung nach ist es am besten, wenn möglich ECS-Weg zu gehen oder etwas näher daran. Informationen zu diesem Ansatz in Unity3D finden Sie unter @ Byte56-Antwort.
quelle
Obwohl die Definitionen variieren können, würde ich Unity3D nicht als Entity System-Engine definieren. Wenn wir über das Entitätssystem sprechen, sollten wir der Adam-Martin-Definition folgen.
Nach seiner Idee sollten die Systeme vom Programmierer erstellt werden, während in Unity3D die "Systeme" in der Engine vordefiniert sind und nicht erweitert werden können.
Dies ist eine alte Methode zum Verwalten von Entitäten und Komponenten. Sie ist eher eine Weiterentwicklung der alten Technik, bei der Spielobjekte Zeiger auf Komponenten enthielten, die mit den Engine-Funktionen kompatibel sind (wie Rendering, Culling usw.).
Wenn es nicht möglich ist, die "System" -Funktionalitäten zu erweitern, besteht die einzige Möglichkeit, die Logik unserer Entitäten zu erweitern, darin, Logik innerhalb von Komponenten hinzuzufügen. Dies ist ohnehin ein Fortschritt gegenüber den klassischen OOP-Techniken. Komponentenorientierte Frameworks (ich nenne sie Entity Component, ohne System) wie das in Unity drücken den Codierer, um Composition gegenüber Inheritance zu bevorzugen, was sicherlich eine bessere Vorgehensweise ist.
Die gesamte Logik in Unity sollte in fokussiertem MonoBehaviour geschrieben werden. Jedes MonoBehaviour sollte nur eine Funktionalität oder Verantwortung haben und nicht außerhalb des GameObject selbst betrieben werden. Sie sollten modular geschrieben sein, so dass sie unabhängig voneinander in mehreren GameObjects wiederverwendet werden können. Monobehaviours enthalten auch Daten und ihr Design folgt offensichtlich den Grundkonzepten von OOP.
Modernes Design neigt stattdessen dazu, Daten von Logik zu trennen. Siehe zum Beispiel die MVC- oder MVP-Muster. Daten, Ansichten und Logik sollten getrennt werden, um eine bessere Codemodularität zu erreichen.
Das eigentliche Problem beim Entwurf von Unity Entity Component besteht in der Komplexität, die erforderlich ist, um zwei Entitäten auf vernünftige Weise miteinander zu kommunizieren, ohne dass verschiedene Anti-Patterns verwendet werden.
Die Einheit kehrt die Kontrolle über die Erstellung von Entitäten um, sodass der Codierer keine Kontrolle über deren Erstellung hat. Das Umkehren der Erstellungssteuerung ist eine gute Sache, aber Unity macht es nicht richtig. Das Nichteinfügen von Abhängigkeiten in Entitäten ist eine Einschränkung, die Codierer dazu zwingt, Anti-Muster zu verwenden, um alle intrinsischen Konsequenzen zu überwinden.
Die sauberste verfügbare Option ist schließlich die Verwendung von Singletons, um Informationen zwischen Entitäten auszutauschen.
Aus diesem Grund ist es mit Unity schwierig, große Projekte zu verwalten und zu warten. Ich habe viel über diese Problematik in meinem Blog geschrieben. Wenn Sie möchten, können Sie dort meine Gedanken weiterlesen:
http://www.sebaslab.com/ioc-container-for-unity3d-part-1/
http://www.sebaslab.com/ioc-container-for-unity3d-part-2/
http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-i-dependency-injection/
http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-ii-inversion-of-control/
http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-iii-entity-component-systems/
http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-iv-dependency-inversion-principle/
http://www.sebaslab.com/the-truth-behind-inversion-of-control-part-v-drifting-away-from-ioc-containers/
In diesen Beiträgen werde ich ausführlich auf die Unity3D-Designfehler eingehen, die die Entwicklung großer Projekte behindern, und sowohl das IoC-Container- als auch das Entity Component System-Framework als mögliche Lösungen.
quelle