Widget Index Problem (Logik Fehler)

  • Hallo zusammen!


    Habe nun ein Auftragssystem in mein Projekt eingebaut und neben dem Inventar und Crafting System, wird in allem Widgets verwendet.

    Sprich das HauptWidget wird erstellt und darin ist eine ScrollBox in der dann entsprechend die "Gegenstände" als Widgets eingelesen werden.


    Jedes Widget hat einen eigenen Index, aber leider kapiere ich nicht wie dort die Reihenfolge funktioniert.

    Ein Widget mit Index fängt bei der Zählung bei 0 an... 0,1,2,3,4,5 usw.

    Der Index wird natürlich durch "ExposedOnSpawn" gemacht, also wenn das Widget dann zum einlesen erstellt wird.



    Leider haben alle Widgets diese Reihenfolge, 0,1,2,3,4,5 usw. weshalb dann die Auswahl (Filter) zu einem Problem wird, wenn man das ganze in einem Array mischen möchte.


    Sprich:

    Inventar Array und darin kommt:

    Waffe (eigenes System)

    Rüstungen (eigenes System)

    Koordinaten, Schatzkarten (eigenes System)

    Aufträge, Lebensmittel usw.


    Also ne Menge Sachen kommen da zusammen und alles fängt an herumzuspinnen, vor allem wenn es gemischt wird.


    Das Inventar funktioniert tadellos wenn es nur eine Sache beinhaltet (also mehrere von einer Art) aber wenn eine zweite Art dazu kommt, geht das nicht mehr.




    Also wie genau funktioniert das mit dem Index in Unreal Engine 4?

    Dazu habe ich schon einige Tutorials geschaut aber die machen das auch nur soweit, wie ich das bereits mache.


    Grob gesagt:


    Ein Struct (weil mehrere Structs da sind) und da "For EachLoop" und den Index davon in das "Create Widget" Index vom erzeugten Widget.

    Ob ich jetzt dazwischen +1 oder +1000 mache, ändert nichts daran.


    Bitte um Hilfe :)



    Hier ein Beispiel als Verbildlichung

  • Was erwartest du denn?


    Du setzt beim erstellen vom Auftrags-Widget eine Int-Variable und fügst es dann der Scrollbox hinzu.

    Am Ende haben die Childs der Scrollbox denn selben Index wie im Auftraege My Character Array.

    Und wie geht das richtig?


    Habe mich schon gewundert das da der Wurm drinnen ist, aber ich komme nicht auf eine alternative Lösung, denn irgendwie funktioniert es ja auch.

  • Schwierig zu beantworten ohne exakt zu wissen was du wie machst. Spawne doch nur die Widgets die du brauchst und wenn es eine Änderung gibt dann kill sie alle und spawne wieder alle die du brauchst. Ansonsten musst du halt einen Weg finden di zu verwalten, am besten durch ein set nach dem Spawn, dann hast du sie als Variable. Da durchzublicken kann dir wohl keiner abnehmen.Aber es klingt als hättest du das schon extrem kompliziert gemacht.

  • Ich möchte 4 StructSysteme die aus 4 InventarArrays in 4 unterschiedliche Widgets in eine gemeinsame WidgetListe eintragen und das so, dass diese sich gegenseitig nicht blockieren.


    Beispiel:

    Heiltrank -> KonsumArray (Inventar) -> KonsumWidget -> HauptInventar Anzeige (ScrollBox)

    Langschwert -> WaffenArray (Inventar) -> WaffenWidget -> HauptInventar Anzeige (ScrollBox)

    usw.


    Ich habe extra mehrere Structuren für Gegenstände gemacht und die muss ich nun in eine ScrollBox als Widgets (wie in einem üblichen Inventar) zusammenführen.

    Aber die Gegestände haben unterschiedliche InventarArrays!


    Das mit den unterschiedlichen Strukturen habe ich extra gemacht damit ich später weniger Probleme mit der Datenbank habe. Alles über ein System laufen zu lassen ist nur am Anfang sinnvoll, später nicht mehr (vor allem wenn ganz viele Sachen hinzukommen).



    Kurz:

    Es werden unterschiedliche Widgets erstellt und die sollen dann in eine ScrollBox gemeinsam angezeigt werden.


    Bilder kann ich dazu keine zeigen, weil das exakt wie oben aussieht, nur eben mit anderen Namen/Arrays, Variablen usw.

  • Gut, du wirst schon deine Gründe haben warum du es so gemacht hast - aber klar - du hast jetzt de Facto 4 Inventare die du verwalten und darstellen musst. Einfacher macht es das nicht. Ja und kalr wenn du 4 verschiedene Inventare hast dann hast du auch verschiedene Indizes und arrays. Es ist nicht unmöglich das so zu machen - ich hätts nicht gemacht, aber wenn du deine Gründe hast wirst du wohl weiter daran knobeln müssen.


    Was genau ist denn das Problem in der Scroll box? Durch die 4 Inventare gehen und alle Namen der Gegenstände reinkloppen wird ja nicht so schwer sein denke ich.

  • Das Problem ist das jedes der Widget das dem ScrollBox hinzugefügt wird, mit dem Index bei 0 beginnt, es muss aber fortlaufend sein.

    Jedes Widget bekommt nur einen Index zur Identifizierung.


    Wenn ich 2 Schwert und 2 Brote in mein Inventar packe. Beide nicht stapelbar.

    Dann habe ich 2x im Inventar ein Widget was mit Index 0,1 beginnt.


    Waffen: 0,1 Index

    Konsum: 0,1 Index


    Klicke ich nun eine Brot an um es zu essen, dann wähle ich sozusagen 2x Index 0 aus (1x Waffe 0 Index) und 1x Brot 0 Index. Also wird eventuell das Schwert ausgerüstet und nicht das Brot gegessen ^^


    Es muss aber so sein:

    Schwert 1 = 1 Index

    Brot 1 = 2 Index

    Brot 2 = 3 Index

    Schwert 2 = 4 Index

    usw.


    Also einfach fortlaufend damit ich auch wirklich das auswähle was ich anklicke.

    Dadurch das 4x ein Widget erstellt wird, gibt es auch 4x die Zahlenreihen folge von 0,1,2,3,4 usw.


    Ich hoffe das ist nun besser verständlich, es ist echt schwer das zu erklären weil das so komisch ist.





    Mein Versuch bisher:

    InventarArray -> LastIndex und diesen dann entsprechend +1 bei den anderen Widgets die eingefügt werden.

    Trotzdem wiederholen sich Index Werte, also ich habe dann 4x Index 10 als Beispiel... :(

  • Nur mal so eine Idee ohne es jetzt ausprobiert zu haben. Aber in der Regel haben dürftest du den Gegenständen ja eine Struktur gegeben haben. Also Eigenschaften, wie Essbar, Brennbar, Stapelbar im Inventory usw.


    Kannst du den Gegenständen da nicht auch einen Key zuweisen mit dem du dann arbeitest an Stelle von dem Index?

  • Ja klar - wenn du 4 verschiedene Inventare hast hast du auch 4x Index 0 und 4x Index 1 usw.. Dem brot Inventar ist der Index deines Waffen Inventars ja herzlich egal. Also entweder machst du ein Inventar dann hast du nen eindeutigen Index oder du musst halt drumherumarbeiten. Also mit structs oder arrays die den Index im Zugehörigen Inventar aufzeichnen.

    • Offizieller Beitrag

    Wie Tomarr sagte, mit keys arbeiten. Sogenannte Identität-schlüssel. Ein Inventar array, der alle Schlüssel beinhaltet. Ein Schlüssel kann auch eine Struct sein, es ist nur ein Oberbegriff von mir. Da gibts viele Möglichkeiten. Spontan fällt mir nur ein, da du evtl 4 Kategorien hast, musst du aus dem Inventar array auslesen können, welche Kategorie es ist, und welches Index von der Kategorie. Dann wird das Array mit der Kategorie aufgerufen und das Index genommen. was auch gehen würde, eine inventar struct array dass 4 weitere Structs von den Kategorien enthält, eins wird davon nur beschrieben, die anderen sind leer und das wäre schon mal ein Index. Wenn das Inventar durchsucht wird, dann werden alle indexe gelesen und wärend dessen abgefragt, ob dieses struct leer, oder voll ist. Dieses wird dann auch angezeigt.

  • Bisher sind es 4 Struct-Inventar-Dinger das wird im laufe der Zeit mehr, trotzdem muss ich eben jetzt schon das ganze so einfach wie möglich machen.


    Ja die Widgets wissen selber was sie sind. Also es gibt ein extra Widget für jedes Struct (anders geht es nicht).

    Das Widget muss das Struct als Variable haben, damit dort der "Gegenstand" (was auch immer es ist) eingespeichert wird.


    Es funktioniert alles soweit perfekt, nur wenn alles zusammen kommt, spielt die Ordnungszahl einen Streich.



    Im Grunde müsste ich nur alle Indexe zusammen zählen und wenn neue hinzukommen, wird die allgemeine Indexanzahl einfach erweitert.


    Vielleicht eine Art Integer-Array wo alle Indexe addiert werden?

    Aber wie mache ich es das mehrfach 0,1,2,3 auch richtig eingelesen wird?


    Den Index brauche ich damit ich in MyCharacter (wenn das Inventar Widget geöffnet ist) durch anklicken des Widgets, entsprechend identifizieren kann, was der Spieler ausgewählt hat und dementsprechend verändern sich die Möglichkeiten der Anwendung.

    Ein Stück Brot möchte ich ja nicht als Helm tragen, einfach ausgedrückt ^^

  • Da gibt es doch verschiedene Möglichkeiten.


    Du gibst deinem Gegenstand eine Struktur mit. die die Eigenschaften enthält.


    Zum Beispiel


    Bezichnung, Key, IstBrennbar, IstAnzihbar, IstEssbar,Schadenswert, Rüstungswert, Nährwert....


    Apfel, 10001, flase, false, true, 0, 0, 8

    Brot, 10002, false, false, true, 0, 0, 15

    Schwert, 20001, flase, true, false, 21, 2, 0

    Lederrüstung, 30001, false, true, false, 0, 14, 0

    Holzscheit, 50001, true, false, false, 0, 0, 0


    Usw. Diese Struktur kannst du natürlich beliebig erweitern und detaillieren. Und du kannst sie sehr gut in BPs abfragen und auswerten.

    • Offizieller Beitrag

    Exaran Du kommst an eine Verlinkung nicht drum herum. Also mit Keys zu arbeiten. Wenn ich mich richtig erinnere, willst du, dass alles ordentlich repliziert wird. Wenn deine Widget schon variablen festhalten, dann kannst du das schon mal vergessen. Deine Variablen, oder Arrays müssen im Charakter bleiben. Im Widget dürfen die structs als variable sein, aber sie dürfen nur zum anschauen sein, und nicht zum nutzen. Dafür verlinkt man wieder zum Charakter.

    Tomarr hat dir da schon ein super anhang gegeben, bei dem ich nur bissl was dazu sage.

    Die Keys werden schon beschrieben, wenn sie in das inventar gelegt werden. Ich würde nicht mit kategorien wie 2000 und 3000 arbeiten, sondern von 0 Anfangen. Immer wenn ein neues Item kommt, dann werden die keys neu beschrieben und von Null angefangen. Das bedeutet, im ersten Array werden die Keys von 0 bis zum Ende beschrieben, und dann gehts weiter mit dem 2. array, der dort mit dem key weiter geht, wo es im ersten aufgehört hat. Später werden sie in eine Gesammtliste "Inventar" eingefügt. Im Inventar ist nur Key interessant. Der wird auch im Widget da gelassen, um in den anderen Arrays danach zu suchen. Normalerweise wäre auch nur die Keys in den Widgets interessant, ohne ein Inventar Array zu nutzen.


    Array: Nahrung

    Bezichnung Key usw
    Apfel 0 ...
    Brot 1 ...


    Array: Rüstung

    Bezichnung Key usw
    Schwert 2 ...
    Lederrüstung 3 ...
    Holzscheit 4 ...



    Array: Inventar (Oder gleich verteilt in Widgets und das hier ist nur die Scrollliste)

    Bezichnung Key Widget
    Apfel 0 Nahrung(Enum)
    Brot 1 Nahrung(Enum)
    Schwert 2 Rüstung(Enum)
    Lederrüstung 3 Rüstung(Enum)
    Holzscheit 4 Rüstung(Enum)
  • Immer wenn ein neues Item kommt, dann werden die keys neu beschrieben und von Null angefangen.

    Sorry, das halte ich für ein schlechtes Design.

    Wenn man schon Keys/IDs/Indizes verwendet dann sollten diese wenigstens für die aktuelle Spiele-Sitzung eindeutig sein.


    Wenn der Spieler einen Heiltrank mit der ID 42 aus dem Inventar in seine Hotbar zieht und danach beim Händler seinen ganzen Schrott verkauft ist nicht mehr sichergestellt das die ID auch wirklich für einen Heiltrank steht. Du brauchst also eine extra Logik um ständig die IDs zu verwalten. Diese Logik bringt aber keinen Vorteil und macht das System nur komplizierter.

    Kommen jetzt noch Beutetruhen und Auktionshaus hinzu hast du irgendwann eine Logik die keiner mehr nachvollziehen und warten kann.


    Apropos Auktionshaus.

    Da es sich um ein Onlinespiel handelt bei dem es ja hoffentlich tausende Spieler gibt, kommt man sowieso nicht um eine Datenbank. Spätestens hier wird man sich mit dem Konzept eines Primär-Key beschäftigen müssen.


    Ich hatte Exaran schon hier zu einer eindeutigen Item-ID geraten, es macht das System viel einfacher.


    Was das replizieren vom Inventar angeht, dem Server sollte es egal sein was der Spieler lokal im Inventar hat.

    • Offizieller Beitrag

    Wenn man keine Datenbank hat, dann kann er das so nutzen wie ich es gesagt habe, wenn die Datenbank genutzt wird, muss er ein schlüssel verwenden der fest geschrieben wird.

    Der Server weis, welcher charakter was für ein Item hat. Da muss man nicht noch erst alle Items Global behandeln. Sollte es aber zum großen Server gehen, der auch die Daten festhalten muss, also Datenbank, dann ist es logisch richtige Schlüssel zu verpassen.

  • Sorry für die verspätete Antwort, die Verwandschaft ist kurz nach dem Neujahr immer recht präsent ^^


    Ich glaube da wurde etwas durcheinander gebracht.


    Ich habe 4 Structs

    1. Ausrüstung-Struct (für alle Waffen, Rüstungen)

    2. Konsum-Struct (für alle Verbrauchsgegenstände)

    3. Material-Struct (für alle Rohstoffe und Bauteile)

    4. Einrichtungs-Struct (für alle Housing Teile)

    weitere Structs folgen noch, etwa Fahrzeug-Struct, Gebäude-Struct usw.


    Damit habe ich alle Gegenstandsarten so aufgeteilt, das diese sich gegenseitig nicht stören (ein Struct in dem alles ist, funktioniert nur am Anfang gut, später gar nicht mehr, weil es dann zu viele Gegenstände gibt).


    Jedes Struct hat ein eigenes Inventar (für jede Kategorie) diese ist im MyCharacter gespeichert, worauf primär der Spieler Zugriff hat, später sollen andere Spieler auch darauf Zugriff haben (aber das ist ein anderes thema).

    4 Inventare: (Array)

    1. AusrüstungsInventar

    2. KonsumInventar

    3. MaterialInventar

    4. EinrichtungsInventar


    Und davon habe ich noch jeweils eine separate Datenbank gemacht die eine ID hat, aber diese Datenbank wird NUR beim Craften (Herstellen) verwendet und darf und soll nicht anderweitig Verwendung finden!


    Jeder Gegenstand im Spiel ist voll veränderbar (darum keine weitere Datenbank Nutzung im Spiel)


    Das Bedeutet das ein Heiltrank soweit und frei modifiziert werden kann, das dieser zusätzliche Eigenschaften bekommt und das unendlich, ohne weitere Einträge in der Datenbank!

    Denn sonst hätte man z.B. nach 10 Jahren gefühlt 1000 Heiltränke und das ist nicht gut.


    So hätte ich dann 4 basis Heiltränke (25,50,75,100% Heilung) und die sind frei Veränderbar, auch mit neuen Eigenschaften aber das ist nur den Spielern möglich die dieses besondere Talent haben.

    Andere Spieler können das nicht, das mache ich nur aus einem Grund, damit der Spielerhandel das wichtigste ist.


    Ich möchte nicht soweit davon abschweifen, denn das Projekt stelle ich euch dieses Jahr noch vor mit allen Funktionen usw.

    Es geht jetzt nur noch darum die kleineren Fehler zu polieren und das "Inventar Index Problem" habe ich fast seit Anfang an.





    Wenn ich 2 Schwerter, 3 Heiltränke, 4 Eisenbarren und 1 Stuhl in das Inventar aufsammele, habe ich im "Allgemeinen Inventar" (es gibt keines) entsprechend die Gegenstände, das nenne ich nur so weil der Spieler davon ja nichts mitbekommt.


    Das Inventar ist ein Widget in dem die Widgets der Gegenstände in eine ScrollBox reingeladen werden.

    Jedes Widget bekommt einen eigenen Index und soll einfach nur der Reihe nach darin geladen werden.


    Eine ID ist so gesehen an der Stelle unwichtig, weil jeder Gegenstand Einzigartig ist!

    Nur die ID in der Datenbank ist wichtig, zum erstellen, aber nicht im weiteren Spielverlauf, weil ja der frei modifizierte Gegenstand (Informationen) weitergegeben wird.


    Es wird also NICHT der Gegenstand gelöscht und einfach nur ID XYZ aus der Datenbank neu gespawnt (wenn man den Gegenstand aus dem Inventar zu Boden werfen möchte), sondern genau der Gegenstand mit allen seinen einzigartigen Modifikationen wird an der stelle erstellt und das ohne Datenbank!

    An der stelle ist es auch ein besonderer Cheat-Schutz, eben weil es keinen Zugriff auf die Datenbank gibt. Nur der Server darf zugreifen und kein Spieler oder sonst etwas.

    Ich weiss das viele andere Entwickler gerne in die Versuchung kommen, die Datenbank in das Spiel einzubauen um daraus direkt im Live-Spiel zu spawnen.

    Aber auch das ist wieder ein anderes Thema.



    Es geht also nur darum mein Inventar-Widget so zu ordnen das es der reihe Nach funktioniert.



    Ich habe den ganzen Aufwand gemacht weil ich es exakt so haben möchte, weil das einer der wichtigsten Features in meinem Projekt ist. Das die Gegenstände frei modifizierbar sind und es auch bleiben.



    PS: Jeder Gegenstand bekommt automatisch von der Unreal Engine 4 eine eigene ID (Unique ID).

    Müsst ihr mal darauf achten wenn ihr Gegenstände in der Welt erzeugt.

    Ich vermute stark das diese ID temporär ist aber das ist ja soweit egal.