Jump to content
Unity Insider Forum

Datensaetze richtig deklarieren


Strooja0108

Recommended Posts

Hallo Leute,

ich habe ein "script" das so aussieht "

Gamesscript

public Genredetails[] GenreList; 
    [System.Serializable]
    public class Genredetails
    {
        public string genreName;
        public float genreEXP;      
        public int genreLevel;
        public int[] nextlevelExp; 
        public int genreUnlocked;
        public int genreUnlockLevel;      

        public int winsTotal;
        public int losesTotal;
        public int winsPerDay;
        public int losesPerDay;

    }

 

Es ist im Prinzip wie eine Bilbiothek mit verschiedenen Genres und deren Details. Jetzt frage ich mich sollte ich das in ein einzelnes script packen (und dann auf ein leeres gameobject?)und wenn ja wie deklariere ich das am besten? Ich moechte auf die Daten von verschiedenen Scripten zugreifen koennen(schreiben und lesen). Zurzeit schreibe ich in jedes Script public Gamesscript gamesscript. Und weise das script im Inspector zu.Das ist aber eine sehr bescheidene Loesung, da ich viele dieser Bibliotheken mit Datensaetzen habe und ich nicht moechte das ich in jedem skript alles deklarieren muss. Ich ware fuer jede Hilfe dankbar

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 10 Stunden schrieb Strooja0108:

Jetzt frage ich mich sollte ich das in ein einzelnes script packen (und dann auf ein leeres gameobject?)und wenn ja wie deklariere ich das am besten?

Ich verstehe zwar die Situation nur sehr wenig, aber das klingt, als wärst du an dem Punkt angelangt, wo "ich habe mit Unity programmieren gelernt" seine Nachteile mit sich bringt. Wenn du anfängst, irgendein Programm mit Java oder so zu schreiben, dann hast du erstmal keine Szene, in der du Objekte hast, die magisch geladen werden, sobald das Programm startet. Selbst bei einer Fenster-Anwendung, wo du heutzutage auch einfach klickibunti deine Knöpfe platzieren kannst, schmeißt du keine Datenhalter-Objekte auf deine UI-Elemente oder so. Dass, zumindest bei weniger komplexen Projekten, 95% deiner Klassen Komponenten sind, die du dann auf GameObjects ziehst, ist schon eine Besonderheit in der Software-Welt. Und man gewöhnt sich ein bisschen sehr daran :)

Es kann, wenn ich deine Situation jetzt überhaupt richtig gesehen habe, sinnvoll sein, Unity mal links liegen zu lassen und mal etwas ganz anderes anzufassen. Java mit BlueJ ist super zum lernen imo, einfach mal Python (sind wieder ne neue Spachen, aber kann trotzdem helfen... oder gerade deswegen), oder halt eine Konsolen-/Fenster-Anwendung mit C#.

vor 11 Stunden schrieb Strooja0108:

Ich moechte auf die Daten von verschiedenen Scripten zugreifen koennen(schreiben und lesen).

Wie gesagt, ich blicke die Situation nicht so ganz... ich nenne einfach mal ein paar Dinge, die du so kannst.

  1. GameObjects in deiner Szene, die Komponenten haben, in denen Daten stehen. Das ist dann sinvoll, wenn die Daten auch Teil deiner Szene sein sollen. Welcher Schalter öffnet welche Tür? Welche Farbe hat das Licht? Wo spawnen Gegner? Wie viel Schaden macht dieser Bereich?
  2. ScriptableObject in den Assets. ScriptableObjects sind unheimlich wichtig, wenn die Projekte anfangen, etwas komplexer zu werden. Man kann auch andere Dinge damit tun, aber die wohl wichtigste Anwendung ist, dass man sie in die Assets erzeugen kann. Sie sind ganz normale Objekte mit serialisierbaren Feldern (also wie bei Komponenten, dass man die Werte im Editor einstellen kann und sie dann gemerkt werden), die in diesem Fall aber nicht in deiner Szene existieren, sondern außerhalb, so wie deine Sounds, 3D-Modelle und Texturen, die überall im Projekt verwendet werden können. Klassisches und imo sehr gutes Beispiel für ScriptableObjects sind Item-Arten in einem RPG. Denk z.B. an Pokémon. Du hast ein Inventar, das als eine Liste von Items daherkommt. Das Inventar soll in jeder Szene funktionieren, und die Items als Prefabs zu definieren wäre doof, weil du eigentlich keine GameObjects in der Szene haben willst, nur damit sie in der Liste auftauchen. Und die Transform-Komponente ist auch überflüssig.
    Also machst du einfach eine ScriptableObject-Klasse (hier hast du eine Vorlage) und schmeißt da deine Felder rein: Item-Name, Wert beim Verkaufen, Referenz auf ein Sprite, um es im UI anzuzeigen, vielleicht noch eine Beschreibung. Dann kannst du im Editor im Asset-Fenster Rechtsklicken, Create, und deine ScriptableObject-Klasse taucht da auf. Dann erstellt du da mehrere Items und kannst die in deine Szene ziehen, um sie zu referenzieren (so, wie du z.B. ein AudioClip auf deine AudioSource ziehst). Wenn du also z.B. eine Schatztruhe hast, kannst eine Schatztruhe-Komponente machen, die ein Item-Feld hat, wo du dann das Item reinziehst, was aus der Kiste rauskommen soll. In deinem Fall kannst du deine Genres als lauter ScriptableObjects machen, vielleicht noch eine weitere SO-Klasse, die eine Liste der Genres enthält, oder du packst gleich alle Genres direkt in die Liste (so wie es jetzt scheinbar ist). Die Entscheidung sollte danach gehen, ob du auf die Genres einzeln zugreifen willst.
    Auch hier müsstest du erstmal ein Feld in deinen Komponenten deklarieren, in das du dann ein SO reinziehen kannst. Diese Variante ist also dann sinnvoll, wenn du mehrere mögliche Objekte (z.B. Genre-Listen) haben willst und dann im Editor durch Reinziehen entscheiden kannst, welches davon deine Komponente benutzen soll.
    ScriptableObject sollte man so oder so mal ansehen, auch wenn das hier am Ende nicht die beste Lösung sein sollte.
  3. Stinknormale Objekte, die nix mit Unity ab Hut haben. Du kannst auch einfach Objekte erzeuge, ohne, dass der Editor die jemals zu Gesicht bekommt. Wenn du im Inspektor Dinge eintragen können willst, ist das natürlich eher weniger die richtige Variante. Wenn du Objekte hast, die zur Laufzeit generiert werden, wie z.B. eine Waffe in Borderlands mit den zufällig gewählten Eigenschaften, dann willst du dafür evtl. ScriptableObjects benutzen um die möglichen Parameter zu definieren (z.B. Waffe "Grüne Pistole", hat Schaden zwischen 3 und 5, kann eines von folgenden Visieren haben, etc.), aber der Waffendrop selbst wäre dann ein ganz normales Objekt, das du mit new erzeugst.

Zusätzlich zu diesen Varianten muss man sich die Frage stellen, wo man überall Referenzen zu den Objekte aufbewahrt. Du kannst z.B. Objekte jeder dieser Varianten statisch referenzieren. Statisch (weiß nicht, ob du "static" schon verinnerlicht hast) bedeutet, dass der Ort fest innerhalb des Programms definiert ist. Wenn du also z.B. eine statische Variable in deine Klasse packst, dann ist es egal, wie viele Instanzen dieser Klasse du hast - die statische Variable existiert nur einmalig in der Klasse selbst. Während du bei nicht statischen Dingen immer angeben musst, von welchem der Instanzen jetzt die Rede ist (ist ja klar - du musst ja definieren, welches deiner Lichter jetzt rot werden soll), musst du das bei statischen Dingen nicht, und so entfällt der Arbeitsschritt, das Objekt irgendwie herauszusuchen (wie du es z.B. durch dein Feld machst, in das du deine Genres ziehst). Statische Dinge sind entsprechend nur dann sinnvoll, wenn du absolut sicher bist, dass du das Ding nur einmalig brauchst. Wenn du sicher bist, dass du nur exakt eine Genre-Datenbank brauchst, dann kannst du diese irgendwo statisch deponieren und von überall aus drauf zugreifen, ohne noch zusätzlich zu spezifizieren, wo das Ding überhaupt ist.

Sieht dann z.B. so aus:

// Die Klase selbst muss nicht statisch sein, aber es verhindert hier, dass wir Instanzen hiervon erstellen.
// Wir wollen ja nur EINE Datenbank haben, und das ist hier die Klasse selbst.
public static class GenreDatabase
{
  public static Genredetails[] GenreList;
}

Damit kannst du jetzt von überall schreiben:

foreach (var genre in GenreDatabase.GenreList)

oder wie auch immer du mit dem Array arbeiten willst. Der Punkt ist: Du schreibst "Klassenname.Variablenname" und fertig. Die große Frage, und da wird jetzt halt einfach Fortgeschritten, ist: Wie bekommst du deine Daten in die statische Welt? Und da gibt's in Unity mehrere Varianten, aber leider einfach keine, die ich als optimal ansehen würde.

Du kannst deine Genres z.B. alle im Code definieren:

public static class GenreDatabase
{
  public static Genredetails[] GenreList;

  [RuntimeInitializeOnLoadMethod]
  private static void Initialize()
  {
    GenreList = new Genredetails[]
    {
      new GenreDetails { genreName = "Foo",
                         genreEXP = 10f,
                         // ...
                       },
      new GenreDetails {
                         //...
                       },
      // ...
    }
  }
}

Das Attribut RuntimeInitializeOnLoadMethod ist hervorragend. Es macht ganz simpel, dass diese Methode einmalig direkt am Anfang des Spiels ausgeführt wird, völlig egal, was für eine Szene du hast oder was da drinsteckt. (Nebenbei: Ein statischer Konstruktor ginge hier auch, aber mit dem Attribut ist man immer auf der sicheren Seite.)

Ist natürlich irgendwie hässlich, solcherlei Daten hart im Code zu definieren. Weil Unitys neues Input-System das auch so macht, finde ich das auch ein bisschen käsig.

Alternativ könnte man ein ScriptableObject mit allen Genres drin machen und das einmalig am Anfang laden in einem statischen Feld referenzieren. Dafür muss man halt irgendwie definieren, wo dieses SO überhaupt liegt. Dafür bietet sich Resources.Load an, auch wenn ich das Ding ja immer gerne vermeide.

public static Genredetails[] GenreList;

[RuntimeInitializeOnLoadMethod]
private static void Initialize()
{
  GenreList = Resources.Load<GenreListScriptableObject>("Name der Datei hier").GenreList;
}

Hier ist wieder das übliche Problem, dass wenn die SO-Datei irgendwie minimal anders heißt oder verschoben wird, erstmal der Code nicht mehr das tut, was er soll.

Eine dritte Variante wäre, ein GameObject in einer Szene zu haben, das dasselbe macht, nur halt ohne Resources.Load, sondern indem man das SO da reinzieht. Da ist halt der Käse dran, dass der Code wieder nicht funktioniert, wenn man im Play Mode eine andere Szene startet und das Objekt da nicht da ist.

So... das war jetzt ne Menge Text. Tut mir auch leid, dich damit so zu bombardieren, und vor allem, dass da nicht mal "die richtige" Lösung drin steckt. Aber Tatsache ist: Du bist mit dieser Frage ganz eindeutig aus dem Noobschutz-Areal draußen. Die Stützräder sind ab, das Tempolimit aufgehoben. Jetzt geht's ans Eingemachte! Da wird es leider immer häufiger vorkommen, dass du Vor- und Nachteile verschiedener Wege analysieren und verstehen musst, um dann einen Weg zu finden, der am wenigsten doof für dich ist. Und du wirst dich immer wieder schlecht entscheiden, die Konsequenzen oft erst Monate später bemerken und einen besseren Weg erst Jahre später entdecken. Willkommen im Club! :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wow Sasha vielen lieben Dank fuer diese super ausfuehrliche Antwort. Das hat mir auf jeden Fall sehr weitergeholfen. Alsooooo fangen wir mal an . xD

Ich glaube die richtige Antwort(meines erachtens)hast du mir schon geschreiben. Ich erklaere vorher nochmal eben genauer was in meinem Spiel passiert.

Also mein Spiel ist ein Tycoon Game. Es ist moeglich das mein Character sich an den PC setzt und dann anfaengt verschiedene Spiele Genres zu spielen. Basierend auf seeeeehr vielen Variablen und Berechnungen wird dann entschieden ob er eine Runde in dem Genre gewinnt oder verliert. Danach faengt das wieder von vorne an. In dieser Liste die ich im Anfangspost beschrieben habe geht es also darum diese Spielergebnisse festzuhalten. Dementsprechend ist es wirklich einfach wie eine Datenbank die man VERAENDERT. NICHT befuellt und verlaengert, sondern die Daten(die ich gerne sauber uebern Inspector eintragen moechte) sollen nur waehrend des spielens veraendert werden. Wie zum Beispiel erfahrungspunkte,oder Siege in dem Genre. Dementsprechend gibt es diese Datenbank auch nur EINMAL in meinem Spiel.  Dementsprechend bin ich davon ausgegangen das Scriptable Objects keine gute Idee sind, weil sich hier ja nur Daten  festlegen lassen aber nicht wirklich veraendern.(wie du mir in einem anderen Post einmal erklaert hast.)

Ich denke den richtigen Weg hast du mit den statischen Variablen schon aufgezeigt. Ausserdem hast du recht das ich zurzeit diese Liste einfach auf einem leeren Gameobject habe um dort bequem die Startwerte zu erstellen. Ich habe das gemacht damit ich nicht wie du in deinem Beispiel :

new GenreDetails { genreName = "Foo",
                         genreEXP = 10f,
                         // ...
                       },
      new GenreDetails {
                         

Die Werte im Code festlegen muss( habe es immer so verstanden das man das so gut es geht vermeiden soll. Was ja auch Sinn ergibt).

Sondern ich es vernuenftig ueber den Inspector befuellen kann.

So sieht das bei mir jetzt aus:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gamesscript : MonoBehaviour
{
    public Genredetails[] GenreList; 


    public class Genredetails
    {
        public string genreName;
        public float genreEXP;      
        public float genreEXPMulti;
        public float[] genrenervous;   
        public int genreLevel;  
        public int[] nextlevelExp;  
        public float genreTrendMulti;   
        public int genreUnlocked;
        public int genreUnlockLevel;
        public int genreEquipt;
        public int genreRang;
        public int[] genreRangEXP;             
        public int[] genreRangExtraZuschauer;
        public int[] genreRangExtraHappy;
        public int[] genreRangExtraAngry;
        public float viewerKids;

        public int winsTotal;
        public int losesTotal;
        public int winsPerDay;
        public int losesPerDay;
        public int optimalInteraction;
        public int currentInteraction;

    }
}

GameListExample.thumb.jpg.5300d2026119fc68b22e2c57fcdd1fe5.jpg

 

 

Ich denke meine Loesung und warum ich das so machen moechte ist einfach ,weil ich so den Endruck habe das es am uebersichtlichsten fuer mich ist.

Ich denke ich werde das jetzt mal probieren zu einer static class umzuwandeln. Nachdem du mein Beispiel jetzt noch einmal ausfuehrlich gesehen hast. Denkst du immernoch das ist eine gute Loesung?

Link zu diesem Kommentar
Auf anderen Seiten teilen

xD Ich habe gerade festgestellt das ich das Script ja garnicht auf ein Gameobjects legen kann, wenn es statisch ist. Und somit ja auch garnicht bequem ueber den Inspector die Werte zuweisen kann. Also habe ich wieder einmal keine Idee wie ich das machen soll. Und jetzt weiss ich auch was du in deinem letzten Abschnitt meinst xD

Link zu diesem Kommentar
Auf anderen Seiten teilen

Richtig erkannt :)static wird manchmal von Leuten, die es kennenlernen, als Allheilmittel verstanden, damit ein Ding auf irgendein anderes Ding komfortabel zugreifen kann. Dabei ist es nur ein Werkzeug von vielen und will (ausschließlich) an passenden Stellen verwendet werden. In Unity hat man mit static das Problem, dass der Editor damit irgendwie so gar nicht umgehen kann. Unity braucht immer ein Objekt, für das es Werte speichern kann. Wenn man sich Odin anschaut - das ist so ein krasses Ding das u.a. einfach Unitys Serialisierungs-Engine (das ist das Ding, was hier die Grenzen setzt, was man im Editor einstellen kann und was nicht) ersetzt, dann geht da schon noch was. Aber ich bin irgendwie kein großer Fan davon, meine Projekte so stark von Odin abhängig zu machen.

Eine Sache würde ich gerne noch etwas genauer beschreiben: ScriptableObjects sind nicht zwangsläufig dafür da, pro Stück eine "Datenbank" zu beinhalten, wie s jetzt deine Komponente tut. Die Dinger sind eher ganz hervorragend dafür, jeder einen Datensatz (also quasi eine Zeile in einer Datenbank-Tabelle) darzustellen. Du machst also so etwas:

[CreateAssetMenu(menuName = "Genre Details")]
public class Genredetails : ScriptableObject
{
  public string genreName;
  public float genreEXP;
  // ...

und baust dir pro Genre in deinen Assets so ein Ding. Dann kannst du nämlich Relationen mit den Genres definieren, indem du sie irgendwo reinziehst. Um auf das Beispiel mit dem Inventar zurückzukommen: Da kannst du dann dein Item-ScriptableObject "Tennisschläger" in eine Schatzkiste in deiner Szene ziehen, um zu definieren, dass man eben einen Tennisschläger aus der Kiste zieht. Würde man ein ScriptableObject bauen, das alle Itemsorten des Spiels in einem Array beinhaltet, dann müsste man ja noch irgendwie spezifizieren, um das wievielte Item der Liste es geht. Und wenn sich da mal die Reihenfolge ändert - kabumm, alle Indizes kaputt.

Ich empfehle also, das einfach mal zu versuchen. Selbst, wenn du am Ende doch einen anderen Weg besser findest. Lohnt sich alleine für den Lerneffekt. Jedes Genre ist durch ein einzelnes ScriptableObject repräsentiert. Das macht auch das Editieren einfacher, als sich durch so eine lange Liste zu wühlen und die aufzuklappen :) Da hast du dann sogar die Suchleiste für Assets zur Verfügung. Wenn du mal eine Liste von allen Genres brauchst, kannst du die immer noch anlegen. Aber in sehr vielen Fällen braucht man die gar nicht. Sehr oft will man einfach mit einem bestimmten Ding arbeiten, und dass es theoretisch noch x andere von der Sorte gibt, ist dann irrelevant. Die Schatzkiste muss halt auch nur wissen, was sie dem Spieler beim Öffnen gibt - nicht, was es sonst noch für Items gibt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke abermals fuer die schnelle Antwort. Ich glaube ich bin da gerade einfach sehr ueberfordert. Das du das Beispiel mit meinem Inventar gebracht hast, finde ich sehr gut das haette ich naemlich auch so angebracht. Genau in in so einer Datenbank habe ich naemlich auch mein Inventar erstellt.

Ich verstehe deinen Post jetzt so, dass ich das alles in Scriptable Objects umwandeln so . Das bedeutet jetzt aber wenn ich einen "Tennisschlaeger" im Shop kaufen wuerde ,dann wuerde ich sobald ich auf den Kauf Button klicke, ein SO vom Tennisschlaeger erstellen. Wenn ich nochmal darauf klicke wird ein zweites SO erstellt. Wenn ich jetzt angezeigt bekommen moechte wie viele Tennisschlaeger ich besitze muss ich alle vorhandenen SO vom Tennisschlaeger zusammen zaehlen um die Anzahl zu bestimmen.Denn soweit ich weiss ist es nicht so einfach ein SO zu erstellen und dann waehrend des Spiels ein Variablenwert  im SO  zu veraendern(wie in diesem Beispiel die Variable Anzahl, sehr praktisch dafuer waere).Denn selbst wenn das Spiel beendet wird, wird der Wert nicht auf den Default wert zurueckgesetzt in einem SO. Bei sowas wie Anzahl kann man vielleicht noch tricksen, aber um nochmal auf das Beispiel von oben zurueck zu kommen. Wenn ich die Variable "totalWins" alle 5 Sekunden veraendere, dann ist doch ein SO nicht der beste Weg oder? Deshalb dachte ich fuer diese Genre List und auch fuer meine Inventarlist, sind Datenbanken am besten . Ich erstelle die Datenbanken gefuellt mit alle Genres und Items. Und muss nur die totalwins bzw. die Anahl veraendern.Somit habe ich auch nicht hunderte SOs in meinem Spiel rumfliegen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich hab das jetzt so probiert ,dass ich zum Start einfach das public Array in das static Array reinkopiere. Aber er meckert schon in der Zeile: GamesList.genreName = PreGamesList.genreName;

NullReferenceException: Object reference not set to an instance of an object
Gamesscript.Start () (at Assets/Scripts/Gamesscript.cs:51)

Die beiden Debug.Logs geben aber richtige Ergebnisse aus.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Gamesscript : MonoBehaviour
{
    public static Gamedetails[] GamesList;

   
    public Gamedetails[] PreGamesList;
    [System.Serializable]
    public class Gamedetails
    {
        public string genreName;
        public float genreEXP;    
        public float genreEXPMulti;
        public float[] genrenervous;  
        public int genreMood;
        public int genreLevel; 
        public int[] nextlevelExp; 
        public float genreTrendMulti;  
        public int genreUnlocked;
        public int genreUnlockLevel;
        public int genreEquipt;
        public int genreRang;
        public int[] genreRangEXP;             
        public int[] genreRangExtraZuschauer;
        public int[] genreRangExtraHappy;
        public int[] genreRangExtraAngry;
        public float viewerKids;
        public float viewerTeens;
        public float viewerAdults;

        public int winsTotal;
        public int losesTotal;
        public int winsPerDay;
        public int losesPerDay;
        public int optimalInteraction;
        public int currentInteraction;

    }

 

  code.jpg.301e62ce9d3657565ffb0135cc20ae05.jpg

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 14 Minuten schrieb Strooja0108:

Das bedeutet jetzt aber wenn ich einen "Tennisschlaeger" im Shop kaufen wuerde ,dann wuerde ich sobald ich auf den Kauf Button klicke, ein SO vom Tennisschlaeger erstellen. Wenn ich nochmal darauf klicke wird ein zweites SO erstellt.

Nein, eher nicht. Geht zwar, ist aber nicht sinnvoll. ScriptableObjects sind dafür da, Daten zu beinhalten, die im Editor gesetzt werden und dann im Spiel überall verfügbar sind. Du würdest also einmalig per Hand im Editor ein SO anlegen, das Tennisschläger-Daten beschreibt: Name, wie er im Spiel angezeigt wird, das Bild, wie viel man beim Verkauf an Geld kriegt... solche Sachen. Was da genau alles drinsteht und was nicht, hängt vom Spielprinzip ab. Bei Pokémon wäre da an Klassen auch schon fast wieder Schluss. Denn der eine Pokéball und der andere sind komplett austauschbar. Da merkt sich das Spiel einfach einen oder mehrere Stacks von Bällen. Da wird dann das ScriptableObject referenziert um zu definieren, welches Item in welcher Zeile ist, und dann gibt's da ne Zahl obendrauf. Bei Borderlands ist das anders: Wenn da ein Gegner eine Waffe fallen lässt, dann ist die Waffe einzigartig. Die Einzelteile werden nach Vorgaben des Waffentyps (der wäre dann in einem SO) zufällig gerollt. Wenn du zweimal eine Conference Call einsammelst, dann hast du trotzdem zwei verschiedene Waffen. Hier willst du dann tatsächlich ein Objekt pro Gegenstand erzeugen. Aber dieses Objekt wäre dann kein ScriptableObject, sondern ein ganz normales C#-Objekt.

Zur Laufzeit ScriptableObjects erstellen ist eine Option, die ich aber selten empfehlen würde.

vor 24 Minuten schrieb Strooja0108:

Wenn ich jetzt angezeigt bekommen moechte wie viele Tennisschlaeger ich besitze muss ich alle vorhandenen SO vom Tennisschlaeger zusammen zaehlen um die Anzahl zu bestimmen.

Siehe Pokémon-Vergleich. Da hast du einfach einen Eintrag in z.B. einer Liste oder einem Dictionary, der sagt, hier sind Objekte vom Typ X (Referenz auf ein SO) und so viele sind es. Bei Spielen, wo du ein Objekt pro Gegenstand erzeugst, weil die Gegenstände nicht austauschbar sind, brauchst du auch eher selten eine Zusammenfassung, wie viele du davon hast. Übrigens muss nicht einmal der Gegenstand selbst austauschbar sein, es kann auch eine Meta-Info sein wie die Postion des Items im Inventar. Wenn man an Diablo denkt, wo man seine Items selber in ein Grid einsortieren muss, da ist das dann schon wieder sinnvoll, selbst, wenn man zwei komplett gleiche Items da rein tut.

vor 27 Minuten schrieb Strooja0108:

Denn soweit ich weiss ist es nicht so einfach ein SO zu erstellen und dann waehrend des Spiels ein Variablenwert  im SO  zu veraendern

Doch doch, das geht. Statt new benutzt man ScriptableObject.CreateInstance und fertig. Aber wie gesaqt, lohnt nicht. In dem Moment benutzt man nämlich keine der Eigenschaften mehr, die so ein ScriptableObject einem bietet, und dann kann man's auch lassen.

vor 28 Minuten schrieb Strooja0108:

Denn selbst wenn das Spiel beendet wird, wird der Wert nicht auf den Default wert zurueckgesetzt in einem SO.

Das ist so nicht ganz richtig. Wenn du ein SO in deinen Assets hast, dann verhält es sich auch wie ein Asset. Genau wie bei einem Material - wenn du Werte eines Assets änderst, dann bleiben diese Werte erhalten. Im Build ist das aber nicht mehr. Denn nur weil eine Änderung im Editor bleibt, bleibt sie noch nicht im Spiel. Ohne explizite Anweisung deinerseits merkt sich ein exportiertes Spiel nämlich gar nichts bis nach dem Beenden.

Der Punkt ist aber trotzdem nicht ganz unwichtig. ScriptableObjects als Assets sind tatsächlich nicht ohne Weiteres gut für dynamische Dinge zu gebrauchen. Schließlich will man auch im Play Mode testen können, ohne sich alles mögliche dauerhaft zu verändern. Hier gibt es zwei Lösungswege.

  1. Man beschränkt sich auf komplett statische (also: unveränderlich, nicht "static") Daten in ScriptableObjects. Das klingt vielleicht etwas komisch, funktioniert aber sehr gut. Du würdest dann deine Genredetail-Klasse in zwei Klassen aufteilen. Die Dinge, die du im Editor einstellst und die unveränderlich sind, packst du in eine SO-Klasse, und die dynamischen Sachen in eine normale Klasse. Letztere kann dann das entsprechende ScriptableObject referenzieren.
  2. Du baust ein bisschen krasses Zeug in deine SO-Klasse, damit die Werte im Editor und die Wertem die sich zur Laufzeit ändern, nicht wirklich in denselben Variablen stehen. Mein dickstes Asset im Asset Store besteht aus ScriptableObjects, die genau das tun. Da kannst du dann mit dem ISerializationCallbackReceiver-Interface arbeiten, um die Werte nach dem Laden in andere Variablen rüberzukopieren, die dann anstelle der Felder benutzt werden, die der Editor dann speichert. Das richtig hübsch zu machen, ist aber recht heftig. Ohne weiteres Zutun kannst du dann nämlich z.B. die aktuellen Werte nicht mehr im Editor sehen.

Variante 1 ist auf jeden Fall einfacher und, wenn man sich erstmal reingefuchst hat, auch weniger abschreckend.

vor 1 Stunde schrieb Strooja0108:

Ich erstelle die Datenbanken gefuellt mit alle Genres und Items.

Das machst du mit ScriptableObjects quasi auch. Die MEnge an SOs, die du hast, stellen dann sozusagen deinen Datensatz dar. ScriptableObjects sind einfacher zu verwenden, weil du sie reinziehen kannst. Dafür wird's irgendwann bei großen (aber ich meine: großen) Datenmengen unhandlich, mit so vielen Dateien zu arbeiten. Eine klassische Datenbank (bzw. Daten-Datei... XML, Json oder so etwas) sind kompakter, und können außerdem ggf. leichter mit externen Programmen bearbeitet werden. SOs kannst du dafür direkt in Unity editieren. Alles Vor- und Nachteile. Du wirst aber keine hunderte SOs rumfliegen haben, denn du erstellst wie gesagt nicht für jeden Item-Drop ein neues.

vor einer Stunde schrieb Strooja0108:

dass ich zum Start einfach das public Array in das static Array reinkopiere

Kopieren ist nicht nötig! Arrays sind Objekte, das heißt, du kannst einfach die Referenz kopieren. Anstatt also dein Auto komplett nachzubauen, um jemandem zu zeigen wie es aussieht, sagst du einfach "da drüben steht es".

Also ganz stumpf

public static Gamedetails[] GamesList;

public Gamedetails[] PreGamesList;

private void Start()
{
  GamesList = PreGamesList;
}

Das ist natürlich damit verbunden, dass du deine SOs gegen Änderungen abhärtest.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Allso erstmal du siehst scheinbar wie kompliziert und dumm ich denke anhand des letzten Falles xD . So logisch das man einfach die Referenz kopieren kann, aber daran hab ich nicht gedacht.

So ich habe mir jetzt mal Zeit genommen und meine Idee von einem Inventar kurz und knapp umgesetzt und hoffe du kannst mir sagen was da schief laeuft. Denn ich habe irgendwie das Gefuehl das ich und du sehr viel zu unerschiedlichen Punkten springen. Ich werde nur noch verwirrter gerade.^^ Ich weiss das man danach eigentlich nicht fragt aber basierend auf meinem Beispiel File. Koenntest du mir das einmal so erstellen wie du sowas machen wuerdest?

Was nach dem Kauf der Getraenke moeglich sein soll ist einfach, dass ich einen anderen Button(Trinken) klicke, der das Menu wieder aufruft und anstatt des Kaufen Buttons habe ich einen Button "Trinken". Wenn ich darauf klicke verschwiendet eines der Getraenke.

 

 

Ps: Wenn du mir auch noch erklaeren koenntest warum die PreItemList sich im Inspector updated(die item anzahl),wenn ich ein neues Item kaufe. Obwohl ich die PreItemList niemals update. Dann waere das echt spitze.

Ich vermute es hat was damit zutun das ItemList static ist. Aber das ist nur eine vermutung.Verstehen wuerde ich es nicht xD

TestInventar.rar

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 1 Stunde schrieb Strooja0108:

Ps: Wenn du mir auch noch erklaeren koenntest warum die PreItemList sich im Inspector updated(die item anzahl),wenn ich ein neues Item kaufe. Obwohl ich die PreItemList niemals update. Dann waere das echt spitze.

Referenzsemantik. Du kopierst ja nur die Referenz, nicht das Objekt (also das Array in diesem Fall). Ich meinte ja

vor 3 Stunden schrieb Sascha:

Anstatt also dein Auto komplett nachzubauen, um jemandem zu zeigen wie es aussieht, sagst du einfach "da drüben steht es".

Was das aber auch bedeutet ist, dass wenn der Typ jetzt ne Brechstange rausholt und auf das Auto einprügelt, dass dann auch tatsächlich dein Auto leidet und nicht eine Kopie. Es gibt ja nach wie vor nur ein Array mit Inhalt. Wenn du also den Inhalt änderst, dann gilt das auch für jeden anderen "Betrachter" des Arrays, ist es egal, über welche Variable du auf das Array zugreifst. Hatte gerade Lust auf das Ding, hier meine Implementation:

Inventory.unitypackage

Ich hab das Inventar einfach komplett statisch gemacht und mit einem Dictionary implementiert. Dadurch ist die Anzahl nicht mehr Teil der SO-Klasse. Die SOs haben nur unveränderliche Propertys. Der Shop (andere Klasse als Inventar) greift darauf zu. Die verfügbaren Items sind mit je einem ScriptableObject gemacht. Alle SOs sind in den Shop reingezogen. So kann man mehrere Shops mit verschiedenen Waren machen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hey Sascha vielen Dank wieder einmal fuer deine Hilfe. Ich bin ganz ehrlich ich habe kein Plan was du in deiner Datei tust. Ich kriege es nicht mal hin es vernuenftig zu laden und auch wirklich was zu sehen. Deswegen habe ich mir die Scripte einfach angeguckt wobei ich da praktisch nichts verstehe. Ich glaube dir sofort das deine Version besser ist. Aber kannst du mir sagen ob mein Weg ein absolutes no go ist? Du schreibst oben

2 hours ago, Sascha said:

Wenn du also den Inhalt änderst, dann gilt das auch für jeden anderen "Betrachter" des Arrays, ist es egal, über welche Variable du auf das Array zugreifst. Hatte gerade Lust auf das Ding, hier meine Implementation:

Und ganz genau das ist ja das was ich moechte. Ich brauche die Daten aus meiner Datenbank in 10 Scripten von daher war es mir wichtig das ich darauf einfach Zugriff habe von ueberal. Den ich jetzt mit dem static weg ja so wie ich es verstehe auch habe. Ich habe in meinem Fall halt nur eine Kaufmenue Datenbank in dem ALLE Items drinstehen. Manche davon werde einfach durch eine variable erst spaeter dazu geschaltet.Aber sie stehen schon von Anfang an drin. Ausserdem ist mein Kaufmenue Datenbank auch gleichzeitig mein Player Inventar. Durch die "Anzahl" weiss ich ja was er besitzt und das lade ich dann einfach wenn ich auf sein Inventar zugreife.

 

Ich denke dein Script ist fuer mich noch viel viel zu hoch.Deswegen nochmal die Frage kann man das so wie ich machen oder ist es einfach kompletter mist??

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 8 Stunden schrieb Strooja0108:

Ich kriege es nicht mal hin es vernuenftig zu laden und auch wirklich was zu sehen.

Du meinst, du kriegst das UnityPackage nicht in dein Projekt importiert? Oder wie?

vor 8 Stunden schrieb Strooja0108:

Aber kannst du mir sagen ob mein Weg ein absolutes no go ist?

Naja, funktioniert ja. Ich denke, das schlimmste was passieren kann wäre, dass du halt irgendwann in Wochen, Monaten oder Jahren merkst, dass es nervig ist, damit weiter zu arbeiten. Ob es um Erweiterungen oder das Finden von Bugs geht. Aber dadurch lernt man dann ja auch. Es muss halt nicht alles beim ersten Versuch perfekt sein. Bei Anfängern nicht, bei Experten aber eben auch nicht. Deshalb ist es eher wichtig, sich die Vor- und Nachteile anzuschauen, die eine Lösung hat.

Bei deiner Lösung würde mich stören, dass die Items halt auf einem GameObject definiert sind. Du kannst daraus ein Prefab machen und dieses Prefab unabhängig von deiner Szene bearbeiten. Dann muss das Prefab aber trotzdem immer irgendwo mindestens einmal sein, wenn du das Spiel testen willst, weil die Items sonst einfach nicht existieren. Dann fällt mir auf, dass du die Items nicht einzeln, sondern in einem Array definiert hast. Das heißt, dass du auch nur in Listenform auf deine Items zugreifen kannst (wie es der Shop tut) und ansonsten einen Index brauchst. Wenn du also eine Schatzkiste oder so haben willst, dann definierst du mit einer Nummer, welches Item sich darin verbirgt, und nicht über den Gegenstand selbst. Mich würde es auch beim Editieren nerven, dass alle Items in so einer dicken Liste drinstecken, die man dann mehrfach aufklappen muss, um etwas zu editieren. Abgesehen von ScriptableObjects fände ich da schon eine XML- oder Json-Datei besser, da kann man mit einem Text-Editor ran.

Das problematischste daran ist das erste. Je komplexer das Projekt wird, umso wichtiger ist es, die Menge an möglichen Fehlerquellen klein und durchschaubar zu halten. Es geht also nicht nur darum, Fehler möglichst zu vermeiden, sondern auch darum, dass wenn ein Fehler auftritt, dieser leicht zu finden ist. Und da kommt "Code-Qualität" ins Spiel. Das sind so Eigenschaften wie Lesbarkeit, Robustheit (dass man für eine Änderung möglichst wenige Codestellen anfassen muss), Modularität (dass man z.B. einen Teil rausnehmen und austauschen kann, ohne dass gleich drei andere Systeme aufhören zu funktionieren) und weitere solcher Dinge. Wenn man da nicht so perfekt abschneidet, ist das halt nicht automatisch ein Beinbruch. Insbesondere, wenn die bessere Alternative noch nicht so einfach von der Hand geht.

Am Ende ist es auch immer eine Frage des Scopes. Wenn du ein Gamejam-Spiel machst oder ganz klare Vorstellungen davon hast, wie groß dein Projekt wird - und dass es nicht besonders komplex wird - dann kannst du sowieso auch einfach dabei bleiben, was du jetzt hast. Wenn sich an dem System nicht mehr viel ändert (wobei man das gerne unterschätzt), dann macht's auch nicht viel. Wie gesagt, im schlimmsten Fall siehst du die Probleme dann irgendwann selber, was sowieso eine gute Sache ist. Denn viele Leute verstehen den Sinn an Code-Qualität nicht, weil sie nie selber "in den Abgrund geblickt" haben. Von daher liegt die Entscheidung bei dir. Ich kann dir sagen, wo Probleme sein können, und ich kann dir auch gerne Fragen zu meinem Code beantworten. Aber am Ende übernimmst du jetzt sozusagen selbst Verantwortung für deinen Code. Und alles so zu machen, wie ich es machen würde, ist vermutlich nicht immer die sinnvollste Entscheidung für dich.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja da hast du schon recht. Ich sehe gerade selbst das es immer umfangreicher wird und schwerer durchzublicken. Ich denke mir zur Zeit aber das ich erstmal alle Funktionen implementiere um zu schauen wie der Spielflow ist. Danach kann ich im schlimmsten Fall nochmal alles neu programmieren. Aber erstmal sollte ich wissen ob meine Spielidee ueberhaupt fuer Spass sorgt.

Zu deinem Example. Wenn ich deine Datei lade, sehe ich nur die scripts unten aber im viewer sehe ich keine Buttons oder sonst was. Also wenn ich das Programm starte sehe ich einfach nichts. Wenn du den Code noch etwas kommentieren koenntest waere das super.Aber ich will auch nicht das du da jetzt zu viel Zeit reinsteckst.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 5 Stunden schrieb Strooja0108:

Wenn ich deine Datei lade, sehe ich nur die scripts unten aber im viewer sehe ich keine Buttons oder sonst was.

Lösche in einem leeren Projekt auch nochmal den Scenes-Ordner und importiere dann den Inhalt des Pakets.

vor 5 Stunden schrieb Strooja0108:

Wenn du den Code noch etwas kommentieren koenntest waere das super.

Joaa... der ist relativ sprechend. Da wüsste ich gar nicht, was ich kommentieren soll. Also, versteh mich nicht falsch: Der ist jetzt nicht zu simpel oder so, aber ich weiß nicht wo ich mit dem Kommentieren anfangen würde, und alles einmal komplett durchkommentieren werd ich eher nicht. Wie gesagt, fragen geht immer :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ah sehr cool jetzt klappts.

Koenntest du diese Zeile erklaeren ?
 private ItemType currentlyDisplayedItem => items[displayIndex];

mBei dieser Zeile, muss man hier keinen Wert angeben wonach er suchen soll? Also nach dem selben namen,oder selben preis. oder muss einfach alles uebereinstimmen?
if (items.TryGetValue(type, out var result))

Bei dieser Zeile, was soll das usepropertyname? Und das (get; private set;)?
[field: SerializeField, UsePropertyName]
    public string title { get; private set; }


Hier updatest du ja den displayindex. Aber wo genau wird das currentlyDisplayedItem geupdated?
public void IncrementIndexAndDisplay(int inc)
    {
        displayIndex = Modulo(displayIndex + inc, items.Length);

        DisplayItem(currentlyDisplayedItem);

Macht das diese Zeile automatisch?  private ItemType currentlyDisplayedItem => items[displayIndex];


Seh ich das also richtig das du einmal SOs nimmst um die einzelnen items festzulegen und dann nochmal ein Dictionary um die Anzahl festzuhalten?
Ich habe sowas aehnliches gemacht.Also bei den Genres habe ich meine Datenbank Variante benutzt wie am Anfang des Threads erklaert. Aber bei meinem Kaufmenue habe ich es ahenlich wie du gemacht.
Nur anstatt SOs habe ich normale Gameobjects benutzt,damit ich auch die Anzahl direkt zu jedem item dazu speichern kann.NAtuerlich habe ich dadurch einen haufen Gameobjekts im Spiel. Aber gibt es sonst nich Nachteile;
 

Was ich aus deiner Scene mitnehme (bis auf ein paar coole Codeschnipsel) Ich sollte probieren alle Arten von Berechnungen in separate static scripts zu packen
um diese dann von anderen scripts einfach aufrufen zu koennen.
Damit umgehe ich diese ewige instanzieren von anderen scripten,dass ich ja sehr viel mache. Ausserdem packst du die scripte auch oft direkt auf die gameobjekte fuer die die scripte bestimmt sind.
Nicht wie ich der ein "Manager" objekt erstellt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

private ItemType currentlyDisplayedItem => items[displayIndex]; 

ist äquivalent zu

private ItemType currentlyDisplayedItem
{
  get
  {
    return items[displayIndex];
  }
}

Es handelt sich also um eine Property, die nur Lesezugriff hat. Auf die Weise kann man currentlyDisplayedItem auslesen und muss nicht immer items[displayIndex] schreiben, was imo weniger sprechend wäre. Immer schön Namen auf alles draufknallen.

vor 2 Stunden schrieb Strooja0108:

Bei dieser Zeile, muss man hier keinen Wert angeben wonach er suchen soll? Also nach dem selben namen,oder selben preis. oder muss einfach alles uebereinstimmen?
if (items.TryGetValue(type, out var result))

"type" ist der Schlüssel. Dictionarys funktionieren wie echt Wörterbücher. Du suchst nach einem Schlüssel und kriegst eine "Übersetzung", also den dazu passenden Wert. Ich stecke "type" rein und kriege "result" raus.

vor 2 Stunden schrieb Strooja0108:

Bei dieser Zeile, was soll das usepropertyname? Und das (get; private set;)?
[field: SerializeField, UsePropertyName]
    public string title { get; private set; }

Das ist ein bisschen sehr fancy. Wird jetzt ne etwas heftigere Erklärung. Du kannst ja

public int number;

schreiben, dann taucht (sofern das jetzt in einer Komponente oder einem ScriptableObject landet) das Feld im Inspektor auf, du kannst was eintragen und es wird gespeichert, als Teil der Szene, des Prefabs, oder eben des ScriptableObjects. Das nennt sich dann "serialisiertes Feld", weil "serialisieren" in diesem Fall den Prozess meint, den Wert in eben diese Datei zu speichern. Hab dazu einen Artikel. In dem steht auch, dass "public" von Unity hier zweckentfremdet wird. Eigentlich sind public und seine Freunde dazu da, zu definieren, ob und wie andere Klassen auf das Ding zugreifen können. Wenn "number" public ist, dann kann ein Objekt einer anderen Klasse ankommen und den Wert verändern. Das will man nicht immer, auch dann nicht, wenn das Feld serialisiert sein soll. Ein privates Feld kann man aber auch serialisieren, und zwar so:

[SerializeField]
private int number;

Jetzt kann Code anderer Klassen nicht mehr mal eben so diese Variable auslesen oder den Wert ändern.

Nun haben wir aber den Fall, dass wir wollen, dass andere Klassen den Titel auslesen können, aber nicht verändern. Weil das hier ein ScriptableObject ist, würde diese Änderung ja permanent sein, sofern sie im Editor-Play-Mode passiert. Das können Felder aber nicht (außer mit readonly, aber das geht nicht mit serialisierten Feldern). Dafür gibt's eben Propertys. Die tun so, als wären sie Felder, erlauben aber sowohl unterschiedliche Zugriffsmodifikatoren (wie eben Lesen public und Schreiben private) als auch etwas Code in den Accessoren (siehe oben, wo kein gespeicherter Wert zurückgegeben wird, sondern einer aus einem Array rausgesucht wird). Damit können wir z.B. das hier machen:

[SerializeField]
private int _number;
public int number => _number;

Damit haben wir eine Property, die den Wert von _number zurückgibt, aber keinen Accessor zum Schreiben hat. Man kann daher nicht

number = irgendwas;

schreiben, das kompiliert gar nicht erst.

Allerdings sind das dann schon drei Zeilen, und es sind mehrere Dinge auf einmal für eine einzige Sache deklariert. Geht zwar, find ich aber nicht so geil. Die bessere Variante ist imo das hier:

[field: SerializeField]
public string title { get; private set; }

Wie du evtl. siehst, haben wie hier eine Property. Das { get; private set; } macht eben, dass andere Klassen nur Lesen können (das Ding selber ist ja public), aber Schreiben ist private. Dadurch, dass die Accessoren keinen Body haben (also ne geschweifte Klammer, in der Code stünde), haben wir hier eine Property mit Backing Field. Das heißt, dass der Compiler automatisch ein unsichtbares Feld generiert, wo der Wert drin gespeichert wird, den diese Property repräsentiert. Und mit "field: " im Attribut können wir Attribute auf dieses Backing Field anwenden. Mit [field: SerializeField] sagen wir Unity, dass es dieses Feld bitte serialisieren soll. Und plopp, taucht es im Editor auf. Allerdings mit seinem echten Namen. Und das lautet, weil der Compiler das generiert und es eh unsichtbar sein soll... "<title>k__BackingField". Mit spitzen Klammern und alles. Das steht dann auch so im Inspektor. Und deshalb hab ich das Attribut UsePropertyNameAttribute geschrieben, das im Projekt eingefügt ist. Das macht nichts weiter, als den hässlichen Namen zu fixen, damit im Inspektor einfach "title" steht :D

Hab ich mit der heftigen Erklärung zu viel versprochen? :D

vor 3 Stunden schrieb Strooja0108:

Hier updatest du ja den displayindex. Aber wo genau wird das currentlyDisplayedItem geupdated?

Gar nicht. Beim Auslesen von currentlyDisplayedItem wird der Code ausgeführt, der in diesem Fall in das Array schaut. Man hätte auch

private ItemType GetCurrentlyDisplayedItem()
{
  return items[displayIndex];
}

schreiben können, denn technisch gesehen ist eine Property nur eine als Feld verkleidete Ansammlung von (wahlweise) einer Setter-Methode, einer Getter-Methode oder eben beidem. Da Java keine Propertys kennt, macht man das da auch genau mit so einer Methode :)

vor 3 Stunden schrieb Strooja0108:

Seh ich das also richtig das du einmal SOs nimmst um die einzelnen items festzulegen und dann nochmal ein Dictionary um die Anzahl festzuhalten?

Jau. Die SOs beschreiben aber alle jeweils nur einen Item-Typ und nicht ein tatsöchliches Item. Also "Schwert" statt "ein Schwert".

vor 3 Stunden schrieb Strooja0108:

Nur anstatt SOs habe ich normale Gameobjects benutzt,damit ich auch die Anzahl direkt zu jedem item dazu speichern kann.NAtuerlich habe ich dadurch einen haufen Gameobjekts im Spiel. Aber gibt es sonst nich Nachteile;

SOs sind halt szenenunabhängig und auch nirgendwo in der Szene versteckt. Würde man meine SOs als GameObjects in die Szene knallen, dann hätten sie eine sinnlose Transform-Komponente und sind semi-willkührlich irgendwo in der Hierarchie eingeordnet. Dinge sollten halt nur dann GameObjects sein, wenn sie auch eine spezifische Rolle in ihrer Szene spielen. Ob sie jetzt irgendwo in der Szene an einem bestimmten Ort sind, sichtbar sind, man dagegen laufen kann, oder ob sie unsichtbar sind und im Hintergrund irgendwelche Dinge regeln. Aber Items wie in diesem Projekt sind in der Regel semantisch völlig von jeglicher Szene losgelöst.

vor 3 Stunden schrieb Strooja0108:

Ich sollte probieren alle Arten von Berechnungen in separate static scripts zu packen
um diese dann von anderen scripts einfach aufrufen zu koennen.

Kommt immer drauf an. Wenn du Funktionen hast, die du immer mal wieder brauchst (wie z.B. Unitys gesamte "Mathf"-Klasse), dann ja, pack irgendwo hin wo du es benutzen kannst. Wenn ein Stück Code aber spezifisch für das Verhalten einer bestimmten Klasse ist, dann darf das da auch gerne drin bleiben.

vor 3 Stunden schrieb Strooja0108:

Ausserdem packst du die scripte auch oft direkt auf die gameobjekte fuer die die scripte bestimmt sind.
Nicht wie ich der ein "Manager" objekt erstellt.

Jau. Wenn eine Klasse das Wort "Manager" auch nur enthält, weiß ich mit 95% Sicherheit, dass die Klasse Käse ist :)

Objekte sollten ihren Kram schön alleine regeln und sich dabei nicht von anderen Objekten ihre Verhaltensweisen vorschreiben lassen. (Lassen wir zwecks einfacherer Formulierung mal ECS außen vor.)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...