Jump to content
Unity Insider Forum

Scriptable Object Variables u. Events in RTS


Hellhound

Recommended Posts

Sagt mal, hat jemand von Euch Erfahrungen gemacht mit ScriptableObject Variablen und Events, wie es von Ryan Hipple auf der United 2017 präsentiert wurde? Ich finde den Beitrag sehr interessant, da ich ein großer Freund von Modularisierung und Entkopplung bin. Ich habe das komplette Konzept dahinter verstanden, allerdings ist das Beispiel wie in Talks üblich ziemlich trivial.

Sobald ich in den Bereich von mehreren Instanzen komme, die sich keine konstanten Daten teilen habe ich jedoch ein Problem. Z.B. wenn ich ein Prefab habe, von dem beliebig viele Instanzen existieren können, wie z.B in einem RTS oder RPG. Eine Überlegung wäre es, beim Instanziieren des Prefabs auch die SO Elemente zu klonen die dynamisch sind, wir wollen ja nicht das alle Instanzen ein und die selben Wert zur Laufzeit hat, z.b. Health.

Nur wie bekommen das die eigentlich entkoppelten Elemente mit, die das Original referenzieren? Irgendwie fehlt mir da die Idee zur richtigen Umsetzung. Hat jemand von Euch sich schon mal daran versucht bzw. eine Idee?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin Hellhound,

ich benutze tatsächlich auch sehr häufig ScriptableObjects sowohl in privaten als auch in professionellen Projekten und mag sie auch sehr. Allerdings gilt für SOs wie für alles andere eben auch das sie stärken und schwächen haben und eben nicht der Heilige Grahl der Spieleentwicklung sind. Sie sind super für settings oder voreingestellte Werte usw. SOs sind für die serialisierung gedacht, also um daten einfach zu Speichern und sie dann auf der Festplatte abzulegen. Ich würde dir nicht empfehlen laufzeit daten, vorallem nicht wenn du mehrere Instanzen hast mit ihnen zu realisieren. Klar geht das keine Frage und um das zur Lauzeit zu realisieren würdest du ScriptableObject.CreateInstance aufzurufen und schon hast du eine geklonte Instanz ohne referenz. Allerings schleppst du bei den SOs eben auch ne menge ballast mit der von Unity kommt und dir jede menge Tooling bietet. Wenn du diese Datenstruktur nun für 10, 100, 10.000 oder noch mehr Instanzen verwenden willst ist das sehr ineffiziet.

Wie gesagt ich benutze SOs eben als Setting oder Blaupause für z.B. Werte für Einheiten. Wenn ich dann eine Instanz von der einheit erzeuge und kopiere die werte von dem SO in ein speziell dafür gedachtes struct das das ganze unnötige Zeug von SOs nicht hat (braucht man zur lauzeit eh aller höchstens beim entwickeln aber nicht mehr im fertigen Spiel).

 

Gruß Cxyda

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin, moin Cxyda,

erst mal danke für die Infos. Wie Du auch setze ich für die Konfiguration meiner Objekte sehr stark Scriptable Objects ein. Mein gesamtes Inventory basiert auf SOs und ist wie ein Baukastensystem 100% dynamisch konfigurier und erweiterbar. Damit bin ich sehr damit zufrieden und fand die Idee sehr charmant Events und geteilte Variablen wie im Talk vorgestellt zu entkoppeln. Zumal ich so recht einfach Daten in andere Szenen oder auch generell übertragen kann.

Ich will auch nicht zu 100% darauf setzen und habe bisher sehr stark auf Events und Delegates gesetzt.  Wollte es mal ausprobieren und hab gemerkt  das es nicht trivial ist. Bin vorhin sogar über einen Blogpost von Ryan gestolpert  wo er selbst sagt, das es nicht trivial ist. Leider sind seine Infos sehr spärlich:

Quote

"roboryantronJanuary 27, 2018 at 8:39 PM

This has been a pretty common question. First, unless you are building a game that focuses on one on one combat, I would not recommend making a scriptable object HP variable for each enemy. The variable examples I gave do not work well in a situation where you have a dynamic set of targets like with a lot of enemy setups. I have a much more in depth system that we are using in the studio now that allows us to instance HP variables per enemy, but it is not trivial. For applying HP meters to various enemies, you could consider a RuntimeSet from my examples. Each enemy could add and remove themselves from the set on spawn and death. Then you could have a system monitoring the set and assigning health UI from a pool. Having a higher level system for the health UI also lets you intelligently lay it out on screen so that it doesn't overlap."

Gruß 

Hellhound 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin Hellhound,

wie gesagt ich würde dir davon abraten da ich den mehrwert nicht so recht sehe ein komplexes system um eine unpassende datenstruktur zu konstruieren nur um SOs zu behalten. Aber gut wenn du das mal testen willst könntest du das schon so machen wie von Ryan beschrieben...

1) Wenn du deinen enemy spawnst registriert er sich bei einer Klasse z.B. dem EnemyHealthSystem
2) Das EnemyHealthSystem kennt alle Health SOs und informiert das UIHealthSystem darüber das eine neue HealthComponente gespawned werden soll (oder kümmert sich selbst drum)
3) Das UiHealthSystem spawned dann für jedes neue element in der liste eine neue UiHealthComponente und updatet die daten... am besten geht das wenn jede Health Componente eine einzigartige ID hat, wie z.B. die enemyID
4) Wenn der enemy stirbt meldet er sich beim EnemyHealthSystem ab und informiert dasUiHealthSystem darüber das die UIComponente despawned werden soll

 

Das beschriebene vorgehen ist das gleiche wenn du keine SOs verwenden würdest. Du musst halt einen weg finden dieses 1:1 mapping (EnemyHealth zu UiHealthComponente) zu finden und das geht am besten mit einer ID. Eine andere möglichkeit wäre das SO direkt zu nehmen und wenn das SO dann zerstört würde davon auszugehen das auch die UIComponente gelöscht werden soll. Aber da Unity den equality comparer von System.Object überschrieben hat führt das manchmal zu seltsamen verhalten das Unity für das SO null zurück gibt (oder auch nicht) während das c# object eigentlich noch da (oder schon null) ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin, Moin, Cxyda83,

habe am Wochenende ein bissl rumgespielt und bin letztendlich auf das Gleiche Vorgehen gestoßen wie Du es beschrieben hast. Das bringt wie Du schon sagst keinerlei Vorteil außer noch mehr Komplexität und unnötiges Objekt geschleppe. Hab es daher abgebrochen und werde weiterhin auf Events und Delegates setzen. Danke Dir für Deinen Input.

Viele Grüße 

Hellhound

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...