Jump to content
Unity Insider Forum

Objekte Speichern und über Instanz neu erstellen/platzieren.


userip

Recommended Posts

Hallo, vielen Dank schonmal im Voraus für die Hilfe. 

Ich habe eine kleine Szene in Unity erstellt, in der ich 3D-Objekte (Prefabs) mit einem Script auf einer "Plane" platzieren kann. Leider fehlt mir die Möglichkeit diese zu speichern.

Ich möchte beim Neustart des Spiels, durch einen ObjectManager der sich diese Objekte gemerkt hat, diese wieder an gleicher Position platzieren lassen (über Instanzen).

Kann mir dort jemand helfen. Über PlayerPrefs kann ich leider keine Objekte speichern. Gespeichert werden muss die Position/Rotation und die Art des Objekt und ein weiterer Float-Wert (den brauche ich später), für mehre Objekte. Wie viele Objekte in einer Szene sind, ist unterschiedlich, je nachdem wie viele der Spieler erstellt hat. irgendwelche Ideen?

Update: Eine meiner ursprünglichen Ideen war es, für jedes Objekt eine PlayerPref von Typ String anzulegen. Etwa so "objectID,objectType,objectPosX,objectPosY,objectPosZ,objectRotX,objectRotY,objectRotZ,value" und das dann immer an den "," wieder aufzusplitten. Mein Problem, da ich nicht weiß, wie viele Objekte es gibt, kann ich nicht einfach alle möglichen IDs durchgehen.

Vielen Dank.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich denke, das du ab diesem Moment die Playerprefs nicht mehr nutzen solltest. Playerprefs snd zwar nicht schlecht, wenn man ein paar Daten speichern will, aber für deine Bedürfnisse sind Playerprefs nicht gut.
Ich würde dir empfehlen das Ganze mit Hilfe von JSON oder einer anderen Art als Textfile zu speichern.
Gespeichert würde dann eine Object ID oder Objektname, die deinem Instanzierer sagt um welches Objekt es sich handelt und die Variablen Informationen, wie die 3 Positionsangaben, die 3 Richtungsangaben(wenn nötig) und interne Werte, wenn es von einem Objekttyp unterschiedliche Varianzen gäbe, wie zB. der Füllgrad einer Trinkflasche.

JSON speichert die Daten immer so ab, dass zuerst ein Variablenname kommt und danach der Wert der Variable. Getrennt wird dann über ein Komma.
So z.B.:
{"ObjectName":"Stein",ObjectGewicht":0.5,"ObjectX":15.4,"ObjectY":0,"ObjectZ:4.2}

Da jeder VariablenName nur einmal in der Datei vorhanden sein kann, setzt du einfach eine Zahl hinten dran. Du vergibst ja selber die Variablennamen und außerdem liest du die ja aus einem Dictionary, einer Liste oder einem Array aus. Dabei ergibt sich eh eine Zahl aufgrund der Position in der Liste/Dictionary/Array oder eines Zählers.

Somit lauten deine Variablen dann "ObjectName1","ObjectGewicht1", "ObjectName2", "ObjectGewicht2" usw.
Das Ganze übergibst du dann JSON (und das geht dann eben solange, bis du am Ende der Liste bist) und daraus wird dann ein String serialisiert, wie oben gezeigt, erzeugt. Den speicherst du als Textfile ab. Je nach Anzahl der Einträgewird dann deine Textdatei länger oder eben kürzer.


Hier ein Beispiel wo die Variable objektdaten ein erzeugter JSON String wäre.

 StreamWriter osw = new StreamWriter(Application.persistentDataPath +"/"+saveName+"_objekte.txt");  // objekte
 //zeile schrieben
 osw.WriteLine(objektdaten);
 osw.Flush();
 osw.Close();  //damit schliessen wir den StreamWriter



Einlesen geht dann genau rückwärts. Textfile wird eingelesen und der String wird über JSON deserialisiert und den Listen oder Dictionarys übergeben. Mittels dieser Werte instanzierst du dann später dein gewünschtes Objekt und übergibst ihm dann seine Positionswerte und Interna.

Hier ein Beispiel wir ich mit miniJSON die Objektdaten eingelesen hatte und sie einem Dictionary übergeben habe:
 

StreamReader osr =new StreamReader(Application.persistentDataPath +"/"+saveName+"_objekte.txt");
var jsonStringObjekte=osr.ReadLine();
osr.Close(); //damit schließen wir unseren StreamReader
            
odict.Clear();
odict=Json.Deserialize(jsonStringObjekte) as Dictionary<string,object>;

 

JSON ist seit einiger Zeit in Unity mit drin, man braucht also eigentlich keine JSON Plugins mehr nutzen.
Schau mal hier:
https://docs.unity3d.com/Manual/JSONSerialization.html

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 1 month later...

könnte man das n icht auch mit ScriptableObjects lösen? einfach für jedes erstellte GameObject dessen Daten in eine Instanz des ScriptableObjects speichern. diese sind dann im Asset gespeichert. 

Ich fuchs mich grad selbst in das Thema ScriptableObjects hinein und für diese Aufgabe sollte es machbar sein, oder?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am 5.6.2018 um 11:20 schrieb malzbie:

JSON speichert die Daten immer so ab, dass zuerst ein Variablenname kommt und danach der Wert der Variable. Getrennt wird dann über ein Komma.
So z.B.:
{"ObjectName":"Stein",ObjectGewicht":0.5,"ObjectX":15.4,"ObjectY":0,"ObjectZ:4.2}

Da jeder VariablenName nur einmal in der Datei vorhanden sein kann, setzt du einfach eine Zahl hinten dran. Du vergibst ja selber die Variablennamen und außerdem liest du die ja aus einem Dictionary, einer Liste oder einem Array aus. Dabei ergibt sich eh eine Zahl aufgrund der Position in der Liste/Dictionary/Array oder eines Zählers.

Ich muss hier mal Korrigieren, Variablename in JSON können pro Datei durchaus mehrfach vorkommen, solange sie nicht in der selben Ebene sind.

JSON unterstützt auch Arrays und verschachtelungen

[
  {
    "objectName": "Object1"
    "position": {
      "x": 14.78,
      "y": 45.785,
      "z": 10.01
    }
  },
  {
    "objectName": "Object2"
    "position": {
      "x": 16.78,
      "y": 44.785,
      "z": 12.01
    }
  }
]

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja gut, das kann sein. Ich habe immer nur mit miniJSON gearbeitet und da ist es nur eine Ebene (soviel ich weiß...). Es gibt außerdem noch andere kleinere Nachteile. Dafür istes schön klein und einfach einzubinden. :)

Ich muss mir unbedingt mal angucken wie das JSON von Unity arbeitet.


 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe in einem projekt beide varianten genutzt. Für Accessoires für den Spieler gibt es ScriptableObjects die bei Generierung per TimeStamp eine ID erzeugen und diese Speichern, dann speichere ich diese Strings mit Trennern und cutte den String dann beim laden und suche nach den IDs. Ebenfalls lade ich Aufgaben und Spieldaten per JSON von einem Server und speichere diese Dann lokal zwischen um beim nächsten Update nur das nötigste zu laden. Für JSON nutze ich das Unity eigene und JSON.Net für Unity.

Link zu diesem Kommentar
Auf anderen Seiten teilen

JSON.Net kann z.B. Daten upgraden, bei Unity überschreibt das FromJsonOverwrite alle Daten, also auch wenn ich kein update vom server habe und somit ein JSON String null ist. Das kann man bei JSON.Net auskoppeln, sodass er alle null Einträge ignoriert und nicht versucht, diese zu ersetzen. Unitys eigenes hatte ich vorher genutzt und läuft jetzt nur als Scriptleiche mit für einfache Daten, bei denen auf jeden Fall alles überschrieben werden soll, wie PlayerDaten Lokal.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...