Du bist nicht angemeldet.

Werbeanzeige

TrommlBomml

Community-Fossil

Beiträge: 2 136

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

11

23.03.2017, 20:23

Ich finde die Darstellung von Renegade auch sehr interessant, weil ich die Vermischung ohne saubere Dependency Injection auch sehr schlecht finde.

Allerdings, wenn ich vom MVC bzw. auch von MVVM komme, kennt hier dein Model/ViewModel (PlayerHealth) den View (EditorReference). Das sollte nach dem Pattern anders herum sein, und anders herum habe ich es auch versucht zu implementieren. Hast du darüber auch nachgedacht oder Gründe gefunden, warum die den View/Editor Reference in deine Logikklassen injectest und nicht andersrum? Das einzige, was mir einfällt: du sparst dir ein Haufen Überwachungen der Views/EditorReferences zu Änderungen in der Logik. Sehe ich das richtig? Mir würde nur noch einfallen, dass man an statt direkt die EditorReference reinzureichen interfaces reinreicht, die die MonoBehaviors implementieren.

Renegade

Alter Hase

Beiträge: 395

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

12

28.03.2017, 20:37

Grüß dich TrommlBomml,

ich hab mal ein paar Tage über deinen Beitrag nachgedacht und überlegt inwiefern ich im Kontext von Unity und allgeimen in Games das MVC sehe.

Es ist ja so, dass bei einer Spiele-Entwicklung (und bei einer regulären Software-Entwicklung denke ich auch) im Idealfall alle Kollegen unabhängig von ein ander arbeiten können und müssen. In der Spiele-Entwicklung betrifft das insbesondere die zwei Lager der Designer und Developer. Das heißt all die ganzen Kollegen die im Level-Design, Character-Design, User-Experience und so weiter arbeiten, benötigen von uns Programmierern Tools womit sie möglichst autonom Features (wenn auch nur als Flow, ohne jegliche Geschäftslogik) umsetzen und diese in die Software einbinden können. Wir Coder arbeiten dann unsere (davon getrennten) Aufgaben im Projektmanagement (z.B. Jira) ab und pushen das Ganze auf den Server (z.B. mittels git). Bei Software mit herrkömmlicher Bedienoberfläche kann man dieses Ziel wirklich sehr elegant mittels MVC oder wie bei WPF mittels XAML (ensprechend MVVM) lösen, weil die View als solches sehr gut definierbar ist und die nötigen Bindings zur "Code-Ebene" sogar generierbar sind. Wir könnten also mittels der erstehende Abstraktionsschicht unsere Geschäftslogik auch anderweitig wiederverwerten - eben die View austauschen.
Bei Spielen, insbesondere in Unity ist die Herangehensweise meiner Meinung nach eine Andere (zumindest an Projekten an den ich gearbeitet habe). In den Vordergrund rückt erst einmal, dass Designer ihre Assets für uns Programmierer korrekt einbinden und verdrahten können. Sollte es tatsächlich möglich sein die View austauschbar zu gestalten, müssen wir uns viel größere Gedanken um all die Ressourcen unserer Designer machen, als um unsere Abstraktionsschicht. Denn viele davon sind an die Engine optimiert, oder in irgend einer Weise (sei es das Level-Design in den Szenen als YAML) speziell dafür konzipiert. Diese Daten (insbesondere die Szene oder Animationen in Mecanim) auf eine neue Engine zu portieren ist ein viel größeres Übel (Bestes Beispiel all die Flash-Frameworks/Spiele die aktuell auf Unity portiert werden). Es geschieht also sozusagen eine viel engere Verbindung zwischen der View und dem tatsächlichen Model. Für mich als Unity Developer ergibt sich daraus als Konsequenz, dass MVC keine geeignete Top-Level-Architektur darstellt, da sie die Dinge in aller erste Linie verkompliziert, ohne mir einen wirklichen Vorteil zu verschaffen.
Versteht mich dabei aber bitte nicht falsch. Ich schließe MVC nicht per se aus. In anderen Subsystem wie z.B. der UI macht es natürlich sehr gut Sinn und sollte dort auch angwendet werden, wenn es entsprechende Vorteile bietet. Allgemein hat sich dabei aber für mich gezeigt, dass das ECS näher an dem ist, was ich für sinnvoll bzw. praktikabel sehe. Denn für mich ist es erstmal nur wichtig die Kommunikationsschicht mit den Designern möglichst flach und einfach zu halten - simple bennante Pakete die ich in der Plannung des Sprints mit meinen Kollegen absprechen kann.
Ich erzeuge also nach Absprache Pakete und reiche sie zu meinen vorgeplanten Konstruktoren durch. Idealerweise rede ich auch noch mit den Designern über den Flow des Features und erzeuge dementsprechend die nötigen Systeme (imo kommt dadurch die Benennung der Dinge auch sehr nah an den tatsächlichen Code) als Vorlage. Sobald die Designer mit ihrer Arbeit fertig sind (oder auch währenddesen) setze ich die benötigten Features um. Dabei betrachte ich die Ressourcen meiner Kollegen weniger als eine View, sondern viel mehr als ein Pool aus Daten.

Um das Ganze noch ein Stück sicherer zu machen und nicht ausschließlich auf öffentliche Felder zu setzen, benutze ich das Vexe Framework (kann ich nur wärmstens empfehlen!) um Properties auch im Editor zu exposen. Das spart mir ebenfalls die unnötige Tipperei für etwaige Schnittstellen die am Ende nichts anderes tun. Außerdem sehr wichtig: dadurch das es in der Szene eine zentrale Stelle gibt, an der das Binding mit all den verstreuten Komponenten/Ressourcen der Designer stattfindet, passiert weniger unnötige Kommunikation (Ich denke nur an all die Stunden in Dokumentation und Meetings). Lieber immer etwas restriktiver dafür aber deutlich und leicht verständlich. Wer mag, fügt noch ein System ein, welches insbesondere Reference Types in den zugewiesenen Komponenten auf ungleich null prüft - im Idealfall zur Erditorlaufzeit als netten Button zum Drücken. Das freut einerseits die Designer die ein tolles grünes Häckchen bekommen, wie auch die Coder die sich unnötige Nullpropagation sparen können.

Interessantes Zeug zum Weiterlesen:
https://github.com/sschmid/Entitas-CSharp
https://github.com/vexe/VFW
https://github.com/mlp1802/PowerInjectUnity
https://github.com/neuecc/UniRx
Liebe Grüße,
René

Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »Renegade« (28.03.2017, 23:24)