Sascha Geschrieben 27. August 2021 Autor Melden Share Geschrieben 27. August 2021 Sind das serialisierte Dinge? 🤔 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
chrische5 Geschrieben 27. August 2021 Melden Share Geschrieben 27. August 2021 Hallo Hier die ganze Klasse: using System; using System.Collections.Generic; using ThirteenPixels.Soda.ModuleSettings; using UnityEngine; namespace Chrische { public class Log : ModuleSettings { #region Variables [SerializeField] private List<string> _allUserEntries = new List<string>(); [SerializeField] private List<string> _absolutAllEntries = new List<string>(); private readonly Dictionary<string, List<string>> _dicEntries = new Dictionary<string, List<string>>(); protected override string title => "My Log"; #endregion public void Write(string entry) { var wholeEntry = DateTime.Now + " " + entry; _allUserEntries.Add(wholeEntry); _absolutAllEntries.Add(wholeEntry); } public void Write(string tree, string entry) { var wholeEntry = DateTime.Now + " " + entry; _absolutAllEntries.Add(wholeEntry); if (tree != "Debug") { _allUserEntries.Add(wholeEntry); } if (!_dicEntries.ContainsKey(tree)) { _dicEntries.Add(tree, new List<string>()); } _dicEntries[tree].Add(wholeEntry); } public void WriteDebug(string message, string className) { Debug.Log("#" + className + "#: " + message); Write("Debug", message); } #region Properties public List<string> AllUserEntries => _allUserEntries; public List<string> AbsoluteAllEntries => _absolutAllEntries; public Dictionary<string, List<string>> DicEntries => _dicEntries; #endregion } } Christoph Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 27. August 2021 Autor Melden Share Geschrieben 27. August 2021 Warum sind diese Listen serialisiert? Steht da im Editor etwas drin, bevor du den Play Mode startest? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
chrische5 Geschrieben 27. August 2021 Melden Share Geschrieben 27. August 2021 Hallo Nein. Habe ich nur gemacht, um im Editor den Inhalt sehen zu können. Christoph Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 27. August 2021 Autor Melden Share Geschrieben 27. August 2021 Dafür ist das aber nicht da xD Wenn du Logs im Editor haben willst, nimm Debug.Log und filtere ggf. die Konsole Serialisierte Felder sind dafür da, dass du Daten im Editor einstellen kannst und diese dann im Spiel vorhanden sind. Wenn du die nur zum Anzeigen von Daten haben willst, dann produzierst du damit nur Datenmüll in deinem Build. Wenn die normale Konsole dir nicht übersichtlich genug ist, schau dir Console Pro an oder mach sonst ein eigenes EditorWindow auf. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
chrische5 Geschrieben 27. August 2021 Melden Share Geschrieben 27. August 2021 Hallo Das ist mir klar. Ich habe mir die Größe und den Inhalt in den project settings angeschaut. Macht das in diesem Fall einen Unterschied? Und wie beantwortet das meine ursprüngliche Frage? Christoph Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 27. August 2021 Autor Melden Share Geschrieben 27. August 2021 Naja, so halb. Die Frage war ja, warum das für statische Service-Klassen gedacht ist und warum man nicht einfach das SO besorgt und für sich arbeiten lässt. ScriptableObjects sind halt grundsätzlich als stumpfe Datenhalte mit minimaler Funktionalität gedacht. Wenn du also ein SO vom ModuleSettings-System besorgst, dann kannst du damit entweder nichts sinnvolles machen außer dessen Daten auslesen, oder du hast die Klasse zu mächtig gemacht. Die statische Service-Klasse ist außerdem ein zentraler Punkt in deinem Projekt, wie z.B. die alte Input-Klasse. Die existiert halt einmalig im Programm und kann von jedem genutzt werden. Die ModuleSettings.Get-Methode ist gleichermaßen von überall aus verwendbar. ModuleSettings.Get zu benutzen, um eine Referenz auf ein Objekt zu kriegen, das sowieso nur einmal existieren soll, ist irgendwie ein Umweg. Und es setzt in jeder verwendenden Klasse Kenntnis über das ModuleSettings-System voraus. Anstatt also Input.GetAxis oder Mathf.Clamp zu schreiben, müsstest du irgendwo UnityServices.Get<Mathf>() schreiben und dann das Ding benutzen, was der zurückgibt. Eine Referenz, die jede Code-Stelle für sich noch einmal neu holen und speichern muss. Es ist einfach ein unnötiger Extraschritt. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
chrische5 Geschrieben 28. August 2021 Melden Share Geschrieben 28. August 2021 Hallo Ich muss noch einmal nachfragen, bitte entschuldige mich, wenn die Frage unsinnig sein sollte. Du sagst also, dass es für den Compiler ein Unterschied ist, ob ich: GameService.GetLog().WriteDebug("no textMesh for news attached", name); oder ModuleSettings.Get<Log>().WriteDebug("no textMesh for news attached", name); schreibe? Wenn nicht, verstehe ich den "Umweg" über die statische Klasse nicht, weil das ja ein zusätzliches Element in meinem Projekt ist, welches ich gar nicht brauche. Wäre das was anderes? public static class GameService { private static Log _log; static GameService() { _log = ModuleSettings.Get<Log>(); } public static Log GetLog() { return _log; } } Hier würde ich den Unterschied verstehen, weil ich bei GetLog() ja nicht immer Get<Log> nutze. Eventuell stehe ich komplett auf dem Schlauch... Christoph Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 28. August 2021 Autor Melden Share Geschrieben 28. August 2021 vor 3 Stunden schrieb chrische5: Ich muss noch einmal nachfragen, bitte entschuldige mich, wenn die Frage unsinnig sein sollte. Keine Sorge vor 3 Stunden schrieb chrische5: Du sagst also, dass es für den Compiler ein Unterschied ist Nein, es geht hier nicht um Performance oder so etwas. Hier geht es nur um simplen und nachvollziehbaren Code. Und darum, Dinge zu benutzen, die für die Situation angemessen sind. Das verringert den Spielraum für Fehler. Deswegen sind Singletons (also: richtige Singletons, nicht das, was man bei Unity als Singleton kennenlernt) ja auch so doof. Statische Klassen gibt's exakt einmal im Programm und man kann keine Instanzen davon erzeugen. Eine nicht-statische Klasse ist dafür da, um eine beliebige Anzahl an Objekten zu erzeugen. Wenn man für einen Service, denes garantiert nur einmal im Programm geben soll, eine nicht-statische Klasse benutzt, dann ist das wirklich kein Beinbruch. Aber es ist halt so ein bisschen an dem vorbei, wofür es da ist. Du kannst halt auch wunderbar mit einer Kneifzange Nägel in die Wand schlagen. Dazu sei gesagt, dass es je nach Kontext andere Regeln gibt. Wenn du z.B. mit Zenject arbeitest, weil du irgendwie Interfaces für Services haben willst, dann benutzt du halt trotzdem Instanzen statt statischer Klassen für deine Service Provider. vor 3 Stunden schrieb chrische5: Wenn nicht, verstehe ich den "Umweg" über die statische Klasse nicht, weil das ja ein zusätzliches Element in meinem Projekt ist, welches ich gar nicht brauche. Da gibt's halt verschiedene Ebenen. Ja, es ist eine Klasse mehr, die übrigens dafür da ist, technische Innereien anderer Systeme zu verpacken. Dass deine Komponenten halt nichts darüber wissen müssen, dass es das ModuleSettings-System gibt. Der Umweg, den du damit aber sparst, ist der zusätzliche Aufruf und ggf. auch das zusätzliche Feld, um die Referenz zu speichern. Ohne statische Klasse: public void Foo() { var logger = ModuleSettings.Get<Logger>(); logger.Log("Foo"); } oder private Logger logger; private void Awake() { logger = ModuleSettings.Get<Logger>(); } public void Foo() { logger.Log("Foo"); } Mit statischer Klasse: public void Foo() { Logger.Log("Foo"); } Stell dir halt vor, du müsstest auch bei Unity ständig Unity.Get<Mathf>() oder Unity.Get<Debug>() machen, um Mathf.Clamp oder Debug.Log aufrufen zu können. An dieser Stelle, also bei der Verwendung, steckt der unnötige Umweg. Die statische Klasse würde dann eben auch das ScriptableObject verbergen, anstatt es rauszugeben, und den Service selber anbieten. Das ScriptableObject soll halt keine Funktionalität haben und nur Daten abspeichern und rausrücken. Du hast jetzt in deinem Beispiel eine statische Klasse, die lauter Services anbietet. Die Idee ist aber, dass du eine Klasse pro Service hast. Also statt public static class GameService { private static Log _log; static GameService() { _log = ModuleSettings.Get<Log>(); } public static Log GetLog() { return _log; } } gibt's public static class Log { private static LogSettings settings; static GameService() { settings = ModuleSettings.Get<LogSettings>(); } public static void Write(string s) { // ... } } Deswegen heißt das System auch "ModuleSettings", weil es dafür da ist, Einstellungen zu laden, nicht um die Services selbst zu verwalten. Das ist aber halt schon pingelig sein auf sehr hohem Niveau. Ist also wirklich kein Beinbruch, wenn du das Warum nicht so ganz sehen kannst. Aber ich hoffe, die Begründung ist jetzt etwas einleuchtender? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
chrische5 Geschrieben 29. August 2021 Melden Share Geschrieben 29. August 2021 Hallo Ahh. Okay. So langsam verstehe ich. Die Idee mit dem GAmeService kam mir auch falsch vor, weil es am Ende ja nur einen anderer Name für Manager ist. Hältst du eine solche Logklasse also eher für ungeeignet für die Settings? Viel mehr als Daten halten, macht die am Ende aber auch nicht. Mit Settings hat es allerdings wenig zu tun. Christoph Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 29. August 2021 Autor Melden Share Geschrieben 29. August 2021 Die Settings sind dafür da, Daten, die man nur im Editor einstellen kann (also Referenzen auf Assets) in seinen Code zu schleusen, ohne dafür irgendetwas in irgendeine Szene einbauen zu müssen. Alle alternativen Wege dafür bedeuten entweder ein Setup, das maintained werden muss. Entweder ein verpflichtendes Einfügen irgendwelcher System-Prefabs in jede neue Szene, eine Initialisierungs-Szene oder Assets im Resources-Ordner. Alle diese Varianten bedeuten, dass da ein im Editor sichtbarer Teil des Projekts nicht angefasst werden darf, wenn man sich im Code nicht auskennt, weil sonst der Code aufhört zu funktionieren. Ich will halt keinem Level-/Game-/UI-Designer sagen müssen "Finger weg von der Build List, dieser Szene und/oder diesem Resources-Ordner". Dagegen sind Code-Dateien und Project Settings für Leute, die keine Ahnung von Code haben, sowieso schon mehr oder weniger tabu Um aber mal direkt zu antworten: Wenn dein dein Log-System aus dem Assets-Ordner nichts braucht, dann ist es in der Tat eher weniger ein Kandidat für das ModuleSettings-System. Allerdings spricht nichts dagegen, auch andere Einstellungen (Zahlenwerte oder Strings oder so) über ModuleSettings einzustellen. Wenn du davon augehst, dass sich diese Einstellungen immer mal wieder während der Entwicklung ändern, dann kannst du es damit vermeiden, den Code immer wieder neu kompilieren und warten zu müssen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
chrische5 Geschrieben 30. August 2021 Melden Share Geschrieben 30. August 2021 Hallo Okay. Dann wäre die Logklasse dann eher ein Kandidat für eine Singleton oder profan eine SODA gloable Variable? Christoph Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 30. August 2021 Autor Melden Share Geschrieben 30. August 2021 Nö, einfach nur eine statische Klasse. Ein Pseudo-Singleton wäre ja nur dann eine Idee, wenn du einen Grund hast, das Ding in der Szene aufzubewahren. Und ein Soda-ScriptableObject ergibt nur dann Sinn, wenn du einen Vorteil davon hast, das über den Editor zu injecten. Aber ein Log-System ist etwas sehr technisches, das im Editor gar nicht sichtbar sein sollte. Du siehst ja auch von Unitys Debug-Klasse keine Spur im Editor. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
chrische5 Geschrieben 30. August 2021 Melden Share Geschrieben 30. August 2021 Hallo So einfach kann die Welt sein. Danke für deine Geduld! Christoph Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 24. Dezember 2021 Autor Melden Share Geschrieben 24. Dezember 2021 Soda ist während des aktuellen Unity Asset Store Sales übrigens um stolze 50% reduziert! https://assetstore.unity.com/packages/tools/integration/soda-scriptableobject-dependency-architecture-137653 2 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
chrische5 Geschrieben 24. Dezember 2021 Melden Share Geschrieben 24. Dezember 2021 Hallo Habe ich schon, aber dein pooling asset habe ich mir gegönnt. Christoph 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.