Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Subsampling

Frischling

  • »Subsampling« ist der Autor dieses Themas

Beiträge: 39

Beruf: Anwendungsentwickler - Azubi

  • Private Nachricht senden

1

28.07.2017, 12:58

Unity - Item/-Objektdatenbank - Best practice?

Hallo Leute,

Weder auf Google noch im Unity Forum hatte ich etwas passendes gefunden/ noch eine Antwort erhalten, weswegen ich mich hier melde.
Ich versuche mich momentan daran in Unity ein kleines Item System zu entwickeln welches mir ermöglicht die ganzen Items/Objekte der Spielwelt zu verwalten.

Als "Datenbank" dient momentan eine XML Datei (ausreichend für die Dimensionen des Spieles). Der Aufbau ist ungefähr so:

C#-Quelltext

1
2
3
4
5
6
7
8
9
<ItemCollection>
  <Item>
   //Daten
  </Item>

  <Item>
   //Daten
  </Item>
</ItemCollection>


Diese XML Struktur habe ich anhand von Klassen (C#) sowie den XMLAttributen in einem C# Skript nachgebildet, sodass ich praktisch jedes <Item></Item> Element als Objekt in meinem Programm erzeugen kann.
Jedes <Item></Item> Element enthält weitere "Unterlemente" welche grundsätzliche Daten wie ItemId, ItemValue, ItemDescription usw. enthalten.
Nun pflege ich in den <Item></Item> Elementen auch einen Tag namens <prefab>Pfad</prefab> welcher eben den Pfad zum benötigten Prefab enthält. Die Item Prefabs liegen wiederum in einer Ordnerstruktur die ich dafür angelegt habe.

Durch die Unity Methoden Instantiate und Ressource.Load<> ist es mir jetzt möglich über die Prefab - Property der Objekte die Prefabs zu laden.

Soviel zur Beschreibung, jetzt zum eigentlichen Problem:

Habe vorher zwar noch kein System in dieser Art entwickelt, jedoch fühlt es sich ein wenig unbeholfen an. Zumal ich einerseits schauen muss das es die Prefabs gibt, andererseits muss ich aufpassen das die Pfade in der XML Datei alle richtig sind. Dann bin ich mir noch unsicher ob man solch ein System in Unity überhaupt so aufbauen sollte.
Habt ihr Verbesserungsvorschläge wie ich das eleganter lösen kann ?

Vielen Dank und Grüße

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Subsampling« (28.07.2017, 15:04)


Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

28.07.2017, 13:03

Gibt es dazu auch irgendeine Frage?
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Subsampling

Frischling

  • »Subsampling« ist der Autor dieses Themas

Beiträge: 39

Beruf: Anwendungsentwickler - Azubi

  • Private Nachricht senden

3

28.07.2017, 13:16

Tut mir Leid,
kann man die Frage sperren/löschen?

Beim Eingeben vom XML Code hat es mir nen Fehler geworfen und alles geschriebene verworfen - das es halb fertig freigegeben wird, war mir nicht klar.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

4

28.07.2017, 13:31

Du kannst den Thread ja editieren und es korrigieren. Ansonsten kann ich ihn aber auch gern löschen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Wirago

Alter Hase

Beiträge: 1 193

Wohnort: Stockerau

Beruf: CRM Application Manager

  • Private Nachricht senden

5

28.07.2017, 19:48

Ich verwende auch XML für meine Itemtabellen. Funktioniert tadellos und ist leicht zu warten. Ist natürlich abhängig von der Menge an Gegenständen. Bei mir werden das nicht so viele sein, so dass XML oder json völlig ausreicht.
Auf Pfade musst du ohnehin immer achten. Habe in meinen zB. als Attribut das Icon das das Item besitzt angegeben (Icon im Inventar). Als fallback gibt es ein fixes default-Icon - also für den Fall, dass der Pfad im XML falsch ist.

Renegade

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

6

29.07.2017, 13:09

Unity ist dafür konzipiert ScriptableObjects und JSON Files zu verwenden. Du schachtelst deine ScriptableObjects ineinander wie du sie im Aufbau benötigst, z.B. so:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[CreateAssetMenu]
public class Inventory : ScriptableObject {
   public Item[] items;
}

[CreateAssetMenu]
public class Item : ScriptableObject {
   public int someData;
   public float evenMoreData;
}

[CreateAssetMenu]
public class GrandSwordOfEpicness : Item {
  public int specialSwordData;
}

Das CreateAssetMenu Attribut bewirkt, dass du über Assets/Create Submenu das Object im Projekt Ordner anlegen kannst (Cool, oder?). Dein Inventory kannst du dann an jedes x-beliebige GameObject anhängen wie du möchtest oder natürlich auch über Resources laden. Wenn du die Daten als JSON repräsentiert benötigst, weil du z.B. mit einem Backend wie Gamesparks o.ä. kommunzierst, kannst du deine Daten mittels der JSONUtility einfach serialisieren. Bedenke das die Utility nur publics serialisieren kann. Ich würde deshalb die ScriptableObjects ausschließlich als Datencontainer verwenden und keine Logik darin platzieren. SciptableObject und die JSONUtility beherrschen im Gegensatz zur Serialisierung von MonoBehaviours die Vererbung. Insofern kannst du dir alle möglichen Konstrukte überlegen, die deine Daten entsprechend abbilden.
Hier noch die wichtigen Links zur Doku:
https://docs.unity3d.com/Manual/class-ScriptableObject.html
https://docs.unity3d.com/ScriptReference…ableObject.html
https://docs.unity3d.com/ScriptReference/JsonUtility.html
https://docs.unity3d.com/ScriptReference…uAttribute.html

PS: Intern werden Assets und Szenen im übrigen mittels YAML serialisiert. http://yaml.org/
Du kannst also theoretisch auch direkt YAML verwenden, wenn du dir die passende YAML Library für .NET besorgst.
Das sieht dann ungefähr bei einem ScriptableObject im Projektverzeichnis so hier aus:
Liebe Grüße,
René

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »Renegade« (29.07.2017, 16:52)


Subsampling

Frischling

  • »Subsampling« ist der Autor dieses Themas

Beiträge: 39

Beruf: Anwendungsentwickler - Azubi

  • Private Nachricht senden

7

30.07.2017, 16:12

Hallo,

erstmal danke für eure Antworten.

@Renegade

Das bedeutet ich könnte mir theoretisch auch einen kleinen Editor/Inspector in Unity basteln, über welchen ich dann alle Items verwalten könnte?
Gleichzeitig kann ich ja dann wiederum mehrere Assets aus meiner "Hauptdatenbank" erstellen, welche dann einen gewissen Satz an Items enthalten und gewisse "Spawn Zonen" repräsentieren?
z.B in Wald Biomen nur Items vom Typ Pflanze oder sonst was.

Dann noch eine Frage für das Verständnis:

Wie sieht aus wenn ich über einen Dienst/ eine App oder externe Datenbank die Items einlesen möchte ?
Sagen wir ich habe ein Feld namens Texture2D welches das Aussehen des Items bestimmt und ich möchte dies eben über eine externe Datenquelle verwalten.
Würde man diese Daten dann in Form eines Pfades zur Textur repräsentieren, würde man da mit anderen Datentypen arbeiten (evtl. Blobs??) oder schreibt man sich da dann Schnittstellen welche die passenden Datentypen interpretieren können?

Vielen Dank für die Mühe,
Grüße,

Renegade

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

8

30.07.2017, 20:54

Hey Subsampling,
Das bedeutet ich könnte mir theoretisch auch einen kleinen Editor/Inspector in Unity basteln, über welchen ich dann alle Items verwalten könnte?

Klar. Bei größeren und komplexen Strukturen macht das auch Sinn. Du kannst jedes ScriptableObject und dessen Struktur für dich als Kategorie verwenden und dafür unterschiedlichste Fenster zur besseren Verwaltung erstellen. Hier findest du den passenden Abschnitt aus der Manual: https://docs.unity3d.com/Manual/editor-EditorWindows.html
Wie sieht aus wenn ich über einen Dienst/ eine App oder externe Datenbank die Items einlesen möchte ?

Hierfür kannst du bekannte Dienste wie Gamesparks, PlayFab oder seit neustem auch Unity Remote Settings verwenden. Die Unity Service Lösung ist dabei noch in den Kinderschuhen - könnte aber deinen Ansprüchen genügen (simple Key Value Pairs, ähnlich in der Bedienung wie die PlayerPrefs). Anbieter wie Gamesparks bieten hingegen sehr viele Möglichkeiten wie Serverskripte oder eine MongoDB. Hier die Links:
https://playfab.com/
https://www.gamesparks.com/
https://blogs.unity3d.com/2017/06/02/int…-in-an-instant/
Sagen wir ich habe ein Feld namens Texture2D welches das Aussehen des Items bestimmt und ich möchte dies eben über eine externe Datenquelle verwalten.

Bei Assets die du nachträglich dem User zur Verfügung stellen möchtest/oder musst (z.B. Updates oder Content Patches) kannst du dich mal in die Materie rund um Asset Bundles einlesen.
Hier die Links:
https://docs.unity3d.com/Manual/AssetBun…pendencies.html
https://unity3d.com/de/learn/tutorials/t…s-and-resources
Liebe Grüße,
René

Subsampling

Frischling

  • »Subsampling« ist der Autor dieses Themas

Beiträge: 39

Beruf: Anwendungsentwickler - Azubi

  • Private Nachricht senden

9

02.08.2017, 23:43

Hallo Renegade,

vielen Dank für deine Mühe!!

Hab mir die ganze Geschichte jetzt mal genauer angeschaut und muss zugeben das mein Vorhaben mit ScriptableObjects nicht wirklich einfacher ist.
Nachdem ich mir mal paar Infos zusammengetragen hatte wie Unity überhaupt seine Bits und Bytes zwischen der C++ und der C# Seite hin und her schubst,
wurde auch schnell klar das es anscheinend durch das System viele "Beschränkungen" gibt.

Am Anfang hatte eigentlich nichts in meinen "Listen" den Assembly Reload überlebt. Erst nachdem ich mit AssetDatabase.AddObjectToAsset alle Items der ItemListe hinzugefügt hatte, sind nach dem Reload auch die Referenzen in der Liste noch vorhanden gewesen.

Auf jeden Fall ein Thema was ich am Wochenende noch vertiefen sollte :/

Grüße!!

Renegade

Alter Hase

Beiträge: 494

Wohnort: Berlin

Beruf: Certified Unity Developer

  • Private Nachricht senden

10

03.08.2017, 12:33

Hallo Subsampling,

ich bin in Projekten ebenfalls schon an die Grenzen von ScriptableObjects gestoßen und kenne die Beschränkungen sehr gut. Möchtest du dich diesen entziehen und die volle Kontrolle darüber erhalten empfehle ich folgendes Vorgehen:
* Du schreibst alle deine Daten als normale Klassen und versetzt sie mit dem [Serializable] Attribut.
* Du schachtelst ggf. diese Datenklassen wie du sie benötigst bzw. wie sie idealerweise auch im Backend dargestellt werden
* Du serialisiert alles mittels JSON über die Utility
* Für deine nun serialisierten JSON Daten schreibst du dir Custom Windows welche dir die Daten wie gewohnt anzeigen. Solltest du gewisse Daten in anderen Form in deiner JSON Datei benötigen als sie Unity bietet (Ein Beispiel was häufig nötig ist: du möchtest ein ObjectField, damit der Designer die Prefabs darein ziehen kann, aber im Hintergrund möchtest du den Asset Pfad innerhalb des Resources Folder) kannst du ein Custom Property Drawer dafür schreiben.
* Deine serialisierten Daten kannst du nun wunderbar in einer MongoDB verwalten, weil MongoDB eigentlich nichts anderes ist als ein riesiger JSON Blob. "How MongoDB Stores Data
MongoDB is a document-oriented database. Instead of storing your data in tables made out of individual rows, like a relational database does, it stores your data in collections made out of individual documents. In MongoDB, a document is a big JSON blob with no particular format or schema.
"
Liebe Grüße,
René

Werbeanzeige