Hier ist eine freche kleine hackische Methode, die die nur im Editor funktioniert . Wir können die DontDestroyOnLoad-Szene nicht namentlich finden, aber jedes DontDestroyOnLoad'ed GameObject enthält einen Verweis darauf. Wenn wir also nur auf ein solches Objekt verweisen (oder ein solches Objekt erstellen), können wir zu allen gelangen:
public void DestroyAllDontDestroyOnLoadObjects() {
var go = new GameObject("Sacrificial Lamb");
DontDestroyOnLoad(go);
foreach(var root in go.scene.GetRootGameObjects())
Destroy(root);
}
Sie können vermeiden, jedes Mal ein Opferobjekt zu erstellen, wenn Sie diese Liste von Objekten bearbeiten müssen, indem Sie auf ein solches Objekt verweisen, von dem Sie wissen, dass es immer vorhanden ist (z. B. das Managerobjekt, auf dem sich dieses Skript befindet), oder indem Sie das ausführen Ritualopfer einmal zu Beginn des Laufs und Zwischenspeichern eines Verweises auf die Szene, der von da an verwendet werden soll (in meinen Tests bleibt es auch dann gültig, wenn alle Objekte zerstört und neue Objekte als DDOL gekennzeichnet wurden).
Beachten Sie, dass dieser Trick laut Dokumentation in einem erstellten Spiel nicht funktioniert :
Sie haben keinen Zugriff auf die DontDestroyOnLoad-Szene und sie ist zur Laufzeit nicht verfügbar.
Beim Versuch, auf diese Szene zuzugreifen, wird eine Ausnahme ausgelöst, die sich darüber beschwert, dass die Szene ungültig ist.
Wenn das rituelle Opfer Ihren Magen dreht (aus gutem Grund, würde ich sagen) oder wenn Sie dies zur Laufzeit in einem gebauten Spiel benötigen , wäre ein konventionellerer Ansatz die Einführung eines DontDestroyOnLoadManager wie folgt:
public static class DontDestroyOnLoadManager
{
static List<GameObject> _ddolObjects = new List<GameObject>();
public static void DontDestroyOnLoad(this GameObject go) {
UnityEngine.Object.DontDestroyOnLoad(go);
_ddolObjects.Add(go);
}
public static void DestroyAll() {
foreach(var go in _ddolObjects)
if(go != null)
UnityEngine.Object.Destroy(go);
_ddolObjects.Clear();
}
}
Dann können Sie jede Instanz einer DontDestroyOnLoad(someObject)
anderen Stelle in Ihrer Codebasis durch ersetzen someObject.DontDestroyOnLoad()
(hier verwende ich eine Erweiterungsmethode, um sie kurz zu halten, aber Sie können sie auch explizit über Ihre Manager-Klasse aufrufen). Dies umschließt das native DontDestroyOnLoad und führt auch die erforderliche Buchhaltung durch, um alle diese Objekte später zu finden. Der Nachteil ist, wenn Sie zusätzliche Skripte und Plugins von Drittanbietern haben, die DontDestroyOnLoad aufrufen, müssen Sie diese ändern, um von diesem System verfolgt zu werden.