|
|
# Problem
|
|
|
Bei einem Szenenwechsel (`SceneManager.LoadScene`) werden alle GameObjects der aktuellen Szene gelöscht. Das betrifft auch zum Beispiel die Position des Spielers oder gesammelte Inventargegenstände.
|
|
|
|
|
|
# Lösung in Unity allgemein
|
|
|
Unity bietet für `MonoBehaviour` Klassen die Methode `DontDestroyOnLoad()` an. Der Methode wird das Objekt übergeben, welches nicht zwischen einem Szenenwechsel gelöscht werden soll.
|
|
|
|
|
|
# Lösung in neueWelt9
|
|
|
Es gibt ein Singleton namens `GlobalStorage`. Auf dieses kann über `GlobalStorage.Instance` zugegriffen werden. Dieses Singleton nutzt intern `DontDestroyOnLoad()` und bietet ein assoziatives Array (Dictionary) an, in dem Daten solange die Anwendung läuft abgelegt werden können. **Darin abgelegte Daten werden nicht auf der Festplatte gespeichert, gehen also verloren wenn das Programm beendet wird**.
|
|
|
|
|
|
Um `GlobalStorage` zu verwenden, muss eine Klasse deklariert werden, welche das Interface `IGloballyStoredObject` implementiert. Diese Klasse dient als Container für die Daten, die man speichern will. Anschließend kann mittels `GlobalStorage.Instance.GetOrCreateByKey(key)` die neu deklarierte Klasse in das assoziative Array eingetragen werden. `key` ist dabei ein string der das gewünschte Objekt eindeutig identifizieren muss. Ist das Objekt nicht im Array enthalten, wird automatisch eine Isntanz davon erstellt und in das Array eingefügt.
|
|
|
|
|
|
## Beispiel
|
|
|
```csharp
|
|
|
// Container for data of interest
|
|
|
class MyData : IGloballyStoredObject
|
|
|
{
|
|
|
// A key to identify this data container
|
|
|
public const string KEY = "Important Data"
|
|
|
// This is persistent across scenes, but not across program launches
|
|
|
public string MyString = "Beständig";
|
|
|
}
|
|
|
// ...
|
|
|
// Whenever you need to access the data in any scene
|
|
|
var data = GlobalStorage.Instance.GetOrCreateByKey<MyData>(MyData.KEY);
|
|
|
// data can't be null
|
|
|
// e.g.
|
|
|
Debug.Log(data.MyString);
|
|
|
|
|
|
```
|
|
|
## Vor- und Nachteile
|
|
|
### Vorteile
|
|
|
* Einfach zu verwenden
|
|
|
* Kann an beliebigen Stellen im Code eingesetzt werden
|
|
|
* Der gleiche Datencontainer kann mit verschiedenen `keys` mehrmals verwendet werden
|
|
|
* Durch die Verwendung eines Interfaces könnte später eine Speicherung auf der Festplatte eingebaut werden
|
|
|
* Einzelnen Programmierern kann es egal sein, was andere Programmierer speichern, solange die `keys` eindeutig sind.
|
|
|
|
|
|
### Nachteile
|
|
|
* Ein falsch geschriebener `key` löst keinen Fehler aus, sondern erstellt ein neues Objekt. Es empfiehlt sich eine Konstante als `key` zu definieren, sodass ein verschreiben erschwert wird.
|
|
|
* Wenn zwei Programmierer den gleichen `key` für andere Objekte nutzen wird einer der beiden das falsche Objekt erhalten (`InvalidCastException`). Es empfiehlt sich den `key` eindeutig zu definieren, z.B. ein Präfix mit dem der Namen der Klasse die das Objekt hauptsächlich verwendet.
|
|
|
|
|
|
# Beispiel in neueWelt9
|
|
|
Für das RunnerGame im Managementcockpit wird die Szene gewechselt. Damit der Spieler nach Beenden des Minispiels wieder im Managementcockpit ist, muss er nach dem Laden der Szene wieder dort hin teleportiert werden.
|
|
|
|
|
|
1. Bevor die RunnerGame Szene geladen wird, speichert das [SwitchScene.cs](https://gitlab.reutlingen-university.de/neuewelt9/nw9/-/blob/uv-testing/neueWelt9/Assets/R%C3%A4ume/EG/Room-9-006/SpeedGame/Scripts/SwitchScene.cs#L47) script in der Hautpszene die Position und Rotation des Spielers und wechselt anschließend auf die RunnerGame Szene.
|
|
|
|
|
|
2. Der [GameManager](https://gitlab.reutlingen-university.de/neuewelt9/nw9/-/blob/uv-testing/neueWelt9/Assets/R%C3%A4ume/EG/Room-9-006/SpeedGame/Scripts/GameManager.cs#L45) des RunnerGames setzt beim Beendes des Minispiels `isReturningFromRunnerGame` auf `true` und lädt anschließend die Hauptszene.
|
|
|
|
|
|
3. Jedes mal wenn die Hauptszene geladen wird prüft SwitchScene.cs [hier](https://gitlab.reutlingen-university.de/neuewelt9/nw9/-/blob/uv-testing/neueWelt9/Assets/R%C3%A4ume/EG/Room-9-006/SpeedGame/Scripts/SwitchScene.cs#L17) ob `isReturningFromRunnerGame` `true` ist und falls ja, teleportiert den Spieler an die in Schritt 1 gepspeicherte Position und richtete ihn entsprechend aus.
|
|
|
|
|
|
|
|
|
# Diagramm
|
|
|
TBD |
|
|
\ No newline at end of file |