Widgets richtig erstellen (+Multiplayer)

  • Die Vorgehensweise ist durchaus OK. Allerdings sollte man trotzdem immer vor der Benutzung abfragen, ob die Variable ihren Wert auch korrekt erhalten hat, bzw. noch immer hat.


    Es gibt immer Möglichkeiten wo es vorkommt das durch einen Programmierfehler Variablen ihren Wert vergessen. Nun würde ich nicht jeden kleinen Integerwert Sicherheitsabfragen oder so. Aber so wichtige Sachen, wie Widgetdaten, kurz vor dem Aufruf, das kann man schnell mal machen. Eben halt auch, weil es wie ja schon erwähnt, nichts Zeitkritisches ist. Also es macht den Programmablauf halt nicht langsamer, spart aber eventuell eine umständliche Fehlersuche.

  • Meine InventarWidget Variable wird schon verwendet, der Screenshot diente nur als Beispiel.


    Mein "HUD" Widget, also das was der Spieler sofort sieht (mit Lebenspunkten, Chat usw.) das lade ich auch mit BeginPlay, aber alles andere, dann nur bei Bedarf oder auf Anfrage.


    ---

    Wieso sollte man abfragen ob sie da ist. Man soll keine Widgets löschen. Damit wollte ich hinaus.

    Dann kann ich also sorglos weiterhin, jedes mal ein neues Widget erstellen wenn ich das Inventar aufrufe?

    Denn löschen sollte man nicht und solange das neue Widget immer in der Variable frisch abgespeichert wird (aus der dann weitere Funktionen genutzt werden), ist alles in Ordnung?


    Was passiert mit den alten, ungenutzten und vergessenen Widgets?

  • Dann kann ich also sorglos weiterhin, jedes mal ein neues Widget erstellen wenn ich das Inventar aufrufe?

    Denn löschen sollte man nicht und solange das neue Widget immer in der Variable frisch abgespeichert wird (aus der dann weitere Funktionen genutzt werden), ist alles in Ordnung?

    Ich glaube, ich hatte das auch etwas falsch ausgedrückt. Du entfernst das Widget beim Schließen ja immer wieder vom HUD. Und an der Stelle solltest du halt abfragen, ob es schon auf ist oder nicht. Wenn ein ganz dummer Fehler kommt, dann hast du sonst irgendwelchen Ärger damit. Ich gebe ja zu, klugscheißen im Forum hin oder her, aber auch ich bin ein fauler Sack und übergehe solche Abfragen gerne mal. Und dann hatte ich plötzlich das Problem das mein, zufälligerweise ebenfalls Inventory, eben halt ganz anders reagierte als erwünscht. Und nach langer Suche war die Lösung halt eine entsprechende Abfrage wie halt der Status ist. Besonders wichtig halt bei Elementen die mit demselben Tastendruck geöffnet und auch wieder geschlossen werden. Schadet aber auch bei allen anderen Elementen nicht, wenn du dir von der Rechenzeit her es dir halt leisten kannst. Beim Rendern selber wäre es natürlich verheerend 1000 mal pro Sekunde noch eine zusätzliche Abfrage zu machen, das kann schon Performance kosten. Aber nicht beim HUD und Inventar usw.

    • Offizieller Beitrag

    Exaran Ich habs jetzt mal für dich getestet.

    Das was ich gelabert habe von RemoveAllWidgets, ist doch nur das selbe wir removeFromParent. Es Zerstört nicht die Widgets.

    Wenn du 10k widgets öffnest und die nur mit CreateWidgets erstellst und nicht mal zum viewport, oder als Child hinzufügst, dann gehen schon 30 - 50mb RAM drauf. Da man Widgets anschein nicht zerstören kann, bleibt es im RAM. Das gilt auch für Widgets als Child. zB Du nimmst ein Item auf, das Widgets wird erstellt und als Child geadded. Das Item wird weggeworfen und es wird mit RemoveFromParent entfernt. Das Widget ist immer noch im RAM vorhanden und kann gefunden werden und weiter genutzt werden.

    Macht das jemand 10k mal, dann wird der Client 10k widgets haben, die er noch nicht mal sieht und 50mb RAM vollgeballert. Ich habe ein Child mit nur ein Button getestet. ICh will nicht wissen, wie das sich mit Texture verhält...

    Entweder haben die Entwickler den Destroy für widgets vergessen, oder es gibt noch eine andere Möglichkeit die wir noch nicht kennen.

  • Alles klar, danke!


    Weil daran habe ich nie gedacht, habe immer fleißig schön "CreateWidget" gemacht, weil halt einfach bequem ist.


    Dann werde ich schauen das ich das optimieren kann.

    Vor allem wenn man sich Items anschaut, summiert sich das ganze viel schneller als wenn man mal sein Inventar aufruft oder so, aber da natürlich auch.



    Ich denke nicht das die Unreal Engine das löschen von ungenutzten Widgets vergessen hat!

    Spätestens bei einem Neustart des Spiels, wird ja alles wieder zurück gesetzt.

    Und bis man mal an die 64 bit Grenze kommt... ob man das überhaupt in der Zeit schaft?


    Ist ja wie mit den Items, Schwert_01, Schwert_02 usw. bis zum nächsten Restart.

    Deswegen müssen die Server auch wöchentlich resetet werden, kann das eventuell auch daran liegen?

    • Offizieller Beitrag

    es ist ja auch nur die Spielsitzung gemeint. Du musst einfach nur Mal das extreme ausprobieren. Ich hab ne Loop erstellt mit 10k loops, und geschaut was passiert.

    Dein Inventar kann mit hide ausgeblendet werden. So sollte das auch sein, damit es nicht ständig neu aufbaut. Probier einfach dein System mit extrem Bedingungen aus

  • Die Blueprints werden ähnlich wie Java, C# und Visual Basic in einen Bytecode - also eine Zwischenstufe zwischen dem Code in der jeweiligen Sprache und dem Binärcode für das System - kompiliert.

    Eine Virtual Machine (VM) (im Falle von Java die Java Virtual Machine [JVM]) führt diesen Bytecode dann aus. So kann die VM mit dem Garbage Collector z.B. Variablen aus dem RAM löschen, wenn diese nicht mehr referenziert werden - bei normalen C++ z.B. müsste man sich selbst darum kümmern.
    Aufgrund dieser Zwischenebene kann es allerdings leichter zu Performanceeinbußen kommen, wie sie oft bei Java Anwendungen (z.B. Minecraft :P) kritisiert wurden. Auch bei Blueprints kann es bei Millionen von Berechnungen deutlich länger brauchen als bei C++-Actors in Unreal.

  • Das Thema widgets und Garbage Collection gab es schon oft. Seit 4.19 werden "removed" widgets auch in der Garbage Collection ordentlich vernichtet. Voraussetzung ist natürlich daß diese nicht mehr aktiv sind, also z.B. keine Timer mehr laufen, usw. Hat man mit der Garbage Collection probleme sollte man also vor dem remove widget evtl Timer oder andere Prozeduren stoppen. Man kann auch mit dem console command "obj gc" die garbage collection manuell anwerfen. Um zu testen wieviele Widgets noch nicht recycled sind bietet sich "get all widgets of class" an (nicht nur top level!).