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.