Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

21

07.11.2014, 13:19

Ich bin mir ziemlich sicher, dass es auch für deine Fälle Lösungsmöglichkeiten gibt. ;)
Sicher gibt es Lösungen und Workarounds. Offensichtlich habe ich die Projekte ja zu einem zufriedenstellenden Abschlus geführt.

Die Probleme mit den Interfaces waren ein Punkt. Desweiteren war es mir nicht möglich, vererbte Properties im Editor angezeigt zu bekommen und ich hatte -- soweit ich mich erinnern kann, Probleme, abgeleitete Klassen als Parameter im Editor zu setzen, wenn das entsprechende Property von Typ der Basisklasse/dem Interface war.
Das ist allerdings auch schon wieder gut ein Jahr her.

Meiner Meinung nach hat Unity also nichts mit einem übermäßigen Aufsplitten der Funktionalität zu tun, sondern nur der Entwickler, der so vorgeht.
Siehe unten.

Wenn ich es nicht total falsch in Erinnerung habe, zeigt der Editor doch problemlos geerbte Properties etc. an. Wo klemmt es denn da bei Vererbungshierarchien?
Das hat zumindest bei mir nicht funktioniert. Ich habe das dann so akzeptiert und halt entsprechend anders strukturiert. Man kann das ja recht einfach mit Strategy-Pattern umgehen.

Ich hab eine zeit lang rumprobiert, welche Konstrukte sich direkt über den Editor anzeigen und editieren lassen. Bin dann zu einer halbwegs guten Lösung gekommen, bei der ich für die Anzeige im Editor eine separate Klasse nutze. Mit Hilfe eines DI Frameworks lässt sich das dann einigermaßen bequem mit den Stellen wo sie benötigt werden verknüpfen. So bleibt auch (abgesehen von dem Editor Glue) der Code Unity frei.
Das würde mich mal interessieren. Kannst du mir mehr dazu sagen?

Das Prinzip hört auf den Namen Entitiy-Component-System und wird recht häufig im Zusammenhang mit Spielen erwähnt und eingesetzt. Es macht bei Unity in Verbindung mit dem Editor auch unglaublich viel Sinn.
...
Und selbst wenn es nicht wiederverwendbare Komponente sind, macht es Sinn. Eine Herausforderung bei der Softwareentwicklung ist es, eine Struktur in den Code zu bringen, damit dieser besser lesbar aka wartbar ist. ... Hier muss man natürlich wieder aufpassen das man die Benennung und Aufteilung logisch nachvollziehbar macht.
Wie gesagt, ich finde Unity ist ein großartiges Werkzeugt um Spiele zu machen und im Gegensatz zu anderen Engies/Toolkits funktioniert es wirklich einwandfrei und hat tollen Support. Es ist eher meine persönliche Meinung und Stil, dass ich mich mit zusammengesteckten Lego-Bausteinen nicht so wohl fühle, wie mit mittelgroßen Klassen.

Vielleicht war das in meinem vorherigen Post zu hart formuliert. Mit Unity hat man, wie mit jeder anderen Engine/Sprache/Toolkit auch, eine gewisse Einarbeitungszeit und muss eben bestimmte Dinge und Richtlinien beachten. Wer womit besser oder schlechter zurecht kommt, das ist wohl vor allem mal wieder persönliche Präferenz.

So Far...
Laguna
Portfolio runvs.io | Gamejolt | itch.io | PEWN | Twitter

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

22

07.11.2014, 13:46

Interfaces:
Bisher habe ich nie probiert, ein Objekt vom Typ eines Interfaces über den Editor zuzuweisen.
Auf Anhieb fallen mir 2 Möglichkeiten ein, die da helfen sollten: entweder wird, wie bereits angedeutet, das Interface in eine abstrakte Klasse umgewandelt oder es wird ein GameObject als Zuweisung seitens Editor erwartet. Da Die von Unity vorgesehene Art der Kommunikation Aufrufe von SendMessage sind, wäre es nichtmal so abwegig. Welche Vorgehensweise besser ist, kommt natürlich auf den konkreten Anwendungsfall an.

geerbte Member:
Wie bereits geschrieben gibt es im Editor keine Probleme mit geerbten Membern. Bist du sicher, dass es in deinem Fall auf Membervariablen und _keine_ Properties waren? Wenn es Properties waren, liegt es nicht an der Vererbung. ;)


@Tobiking:
Mich würde auch interessieren, was du da entwickelt hast und vor allem, für welchen Anwendungsfall du es einsetzt. Bisher klingt es nach Klassen mit dem Attribute [System.Serializable], was ich bisher kaum bis gar nicht benötigt habe.
Seinen Code grundsätzlich Unity-frei halten zu wollen halte ich nicht grundsätzlich für sinnvoll. Algorithmen, Strukturen und ähnliche Dinge kann man ohne Probleme so schreiben, bei allem anderen kommt man nicht sinnvoll drum herum.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

23

07.11.2014, 14:55

Ich spiel mal Devil's Advocate:
"Warum sollte mans denn anders machen?"

Wenns funktioniert, ists doch prima. Merkt später kein Schwein ob du da nun händisch serialisiert hast oder nicht.

Wer Unity nimmt, um dann möglichst sauber und fein programmieren, hat sowieso schon den ersten Fehler gemacht.
Es ist nunmal nicht der Anspruch von Unity, perfekten Code zu schreiben den man sonst überall verwenden kann.
Das heißt nicht wie gesagt, dass man in Unity nur schludern kann, aber die Priorität liegt einfach woanders.
WIP Website: kevinheese.de

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

24

07.11.2014, 15:18

Ich spiel mal Devil's Advocate:
"Warum sollte mans denn anders machen?"

Wenns funktioniert, ists doch prima. Merkt später kein Schwein ob du da nun händisch serialisiert hast oder nicht.
Gegenfrage: warum überhaupt sauberen Code schreiben? Wenn's funktioniert, ist's doch prima. Es merkt später kein Schwein, ob man da nun händisch serialisiert oder nicht.
Oh wait...
(Der Punkt der Serialisierbarkeit ist für den Editor relevant, da darin nur serialisierbare Elemente angezeigt und angepasst werden können bzw. da nur solche automatisch gespeichert und im Spiel selbst geladen werden können. Das hat also nur indirekt mit der Sauberkeit zu tun.)

Wer Unity nimmt, um dann möglichst sauber und fein programmieren, hat sowieso schon den ersten Fehler gemacht.
Die Entscheidungsgrundlage für oder gegen eine Engine oder ein Framework ist eher Featureumfang, mitgelieferte Tools, mitgelieferte Ressourcen, vorhandene Dokumentation und Support usw.
Die Sauberkeit der Programmierung ist also nicht Teil der Entscheidungsgrundlage, die Verwendung einer Engine ist aber keine Ausrede für den Verzicht darauf.

Es ist nunmal nicht der Anspruch von Unity, perfekten Code zu schreiben den man sonst überall verwenden kann.
Bei der Entwicklung von Unity wurde wohl darüber nachgedacht, wie genau die Engine aufgebaut sein soll, bspw. dass es ein komponentenbasiertes System gibt, dass die Kommunikation unter den Komponenten mit SendMessage stattfindet, dass es eine Hirarchie innerhalb der GameObjects geben kann und noch viele weitere Apsekte. Ob nun Programmierer "sauber" oder "unsauber" vorgehen, kann die Engine vielleicht ein wenig beeinflussen, sie kann es aber beim besten Willen nicht steuern.

Das heißt nicht wie gesagt, dass man in Unity nur schludern kann, aber die Priorität liegt einfach woanders.

Nicht bei mir. ;)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

KeksX

Community-Fossil

Beiträge: 2 107

Beruf: Game Designer

  • Private Nachricht senden

25

07.11.2014, 16:09

Ich spiel mal Devil's Advocate:
"Warum sollte mans denn anders machen?"

Wenns funktioniert, ists doch prima. Merkt später kein Schwein ob du da nun händisch serialisiert hast oder nicht.
Gegenfrage: warum überhaupt sauberen Code schreiben? Wenn's funktioniert, ist's doch prima. Es merkt später kein Schwein, ob man da nun händisch serialisiert oder nicht.
Oh wait...
(Der Punkt der Serialisierbarkeit ist für den Editor relevant, da darin nur serialisierbare Elemente angezeigt und angepasst werden können bzw. da nur solche automatisch gespeichert und im Spiel selbst geladen werden können. Das hat also nur indirekt mit der Sauberkeit zu tun.)


Das ist keine Gegenfrage, sondern genau die gleiche Frage. xD

Ich habe nicht umsonst geschrieben, dass ich Devil's Advocate spiele. Also: Warum ist deine Priorität auf sauberem Code? Und warum verwendest du dann Unity? Unity ist im grundlegendem Design doch schon vorgegeben was Codestruktur angeht. Bloß heißt das nicht, dass man daraus nichts tolles und effizientes machen kann.

Zitat


Wer Unity nimmt, um dann möglichst sauber und fein programmieren, hat sowieso schon den ersten Fehler gemacht.
Die Entscheidungsgrundlage für oder gegen eine Engine oder ein Framework ist eher Featureumfang, mitgelieferte Tools, mitgelieferte Ressourcen, vorhandene Dokumentation und Support usw.
Die Sauberkeit der Programmierung ist also nicht Teil der Entscheidungsgrundlage, die Verwendung einer Engine ist aber keine Ausrede für den Verzicht darauf.


"Nicht Priorität" != "Verzicht". Es geht darum ob du jetzt deine halbe Entwicklungszeit damit verbringst, Unitys Fehler auszumerzen (was man durchaus machen kann, denn es gibt viele kleinere Probleme), oder damit einfach lebst und akzeptierst, dass es nunmal Einschränkungen gibt.

Zitat


Es ist nunmal nicht der Anspruch von Unity, perfekten Code zu schreiben den man sonst überall verwenden kann.
Bei der Entwicklung von Unity wurde wohl darüber nachgedacht, wie genau die Engine aufgebaut sein soll, bspw. dass es ein komponentenbasiertes System gibt, dass die Kommunikation unter den Komponenten mit SendMessage stattfindet, dass es eine Hirarchie innerhalb der GameObjects geben kann und noch viele weitere Apsekte. Ob nun Programmierer "sauber" oder "unsauber" vorgehen, kann die Engine vielleicht ein wenig beeinflussen, sie kann es aber beim besten Willen nicht steuern.


Steuern nicht, aber "ein wenig beeinflussen" ist doch wohl schon etwas untertrieben. Alles in Unity ist ein Actor, jede Komponente erbt von MonoBehaviour und und und.


Was ich damit sagen will:
Unity ist flawed und an vielen Ecken kann man daran nichts ändern. Natürlich sollte man selber den bestmöglichen Code schreiben, aber der ist einfach immernoch durch Unity limitiert und daran wird man nicht viel ändern können ohne viel Zeit zu investieren. Zeit, die man anders hätte investieren können.
WIP Website: kevinheese.de

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »KeksX« (07.11.2014, 16:29)


Tobiking

1x Rätselkönig

  • Private Nachricht senden

26

07.11.2014, 16:30


Seinen Code grundsätzlich Unity-frei halten zu wollen halte ich nicht grundsätzlich für sinnvoll. Algorithmen, Strukturen und ähnliche Dinge kann man ohne Probleme so schreiben, bei allem anderen kommt man nicht sinnvoll drum herum.

Vorweg als Disclaimer muss ich sagen, dass es bisher nur einen Prototyp gebaut habe, und ich nicht sagen kann ob die Struktur noch Sinn macht wenn das Projekt in verschiedene Richtungen wächst. Es kann durchaus zu idealistisch sein und ist vermutlich etwas over engineered.

Mein Ziel war meine Erfahrung aus großen "normalen" C# Projekten der letzten Monate in Unity umzusetzen. Ein flexibles Design hängt oft mit der Minimierung von festen Abhängigkeiten zusammen. Als gute Grundlage dafür eignet sich meiner Meinung nach Klassen so zu schreiben, als möchte man hinterher noch Unit Tests dafür schreiben. Also Interfaces nutzen, Abhängigkeiten von außen auflösen, "keine Singletons", static Klassen oder andere globale Konstrukte, usw.

Als Basis für die Architektur nutze ich Zenject als DI Framework. Es gibt eine Hauptszene, die nicht viel mehr tut als ein paar Standardbindings zu setzen und dann andere Szenen (Levels, Menus etc.) dazu läd. Wenn eine Szene geladen wird, werden in den Objekten die Abhängigkeiten auf Services wie Zeit, Input etc. aufgelöst. Dabei haben die Szenen aber auch die Möglichkeit die Bindings auszutauschen. So könnte man in einem Level z.B. den Zeitservice durch einen austauschen, der halb so schnell läuft, oder die Steuerung umkehren. Sind vielleicht nicht die besten Beispiele, aber soll verdeutlichen, dass das System entsprechend flexibel ist.

Das Gleiche lässt sich sicher auch ohne dem komplexen Drumherum erreichen. Mir fielen da zwei Wege ein:
1. In jede Szene ein globales Objekt packen das die Zeit, Input etc. regelt. Über einen festen Namen kann man darüber zugreifen.
2. Es gibt eine Art Level Script, dass vielleicht von einer Basisklasse erbt und dann Verhalten überschreibt.

Option 1 sehe ich problematisch bei größerer Szenen Zahl. Für das Spiel waren 20 Level angedacht. Das heißt in mindestens 20 Szenen darauf achten, dass das globale Objekt da ist und alle Skripte hat bzw. vor jedem Release und Update dann jedes Level antesten um sicher zu sein.
Option 2 kann zu einer ziemlich großen Basisklasse führen und bei unerwarteten Anforderungen doch zu unflexibel werden.

Den größten Vorteil bei meinen Ansatz sehe ich darin, dass ich Abhängigkeiten über den Code auflöse und nicht über die Szene. Zudem hat Zenject die Möglichkeit Bindinds statisch zu prüfen, während man ansonsten durchprobieren muss.


Mich würde auch interessieren, was du da entwickelt hast und vor allem, für welchen Anwendungsfall du es einsetzt. Bisher klingt es nach Klassen mit dem Attribute [System.Serializable], was ich bisher kaum bis gar nicht benötigt habe.

Ich habe bei meinen Szenen im Prinzip nur eine Stelle in der es globale Werte geben kann, und das ist der Installer, der sich um die Bindings kümmert. Dort wollte ich mehrere Werte in verschiedenen Kategorien haben, also entsprechend schachteln. Mit einem Property auf eine Serializable Klasse, die wiederum Properties auf Serializable Klassen hat, kam ich dann zum gewünschten Ergebnis. Ich brauchte es halt auch entsprechend in Kategorien, da ich danach separate Bindings draus gemacht habe. Einfach die advanced Version von https://github.com/modesttree/Zenject#us…figure-settings

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

27

07.11.2014, 18:29

Die von Unity vorgesehene Art der Kommunikation Aufrufe von SendMessage sind, wäre es nichtmal so abwegig.

Es ist möglich ganz ohne SendMessage zurecht zu kommen. Ich finde es viel besser die Komponente direkt anzusprechen(transform.GetComponent<Foo>().Bar()). Dann funktionieren die Refactoring-Tools auch viel besser.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Werbeanzeige