Đây là một phương pháp hackish táo tợn chỉ hoạt động trong Trình chỉnh sửa . Chúng tôi không thể tìm thấy cảnh DontDestroyOnLoad theo tên, nhưng mỗi GameObject của DontDestroyOnLoad'ed đều có tham chiếu đến nó. Vì vậy, nếu chúng ta có một tham chiếu đến chỉ một đối tượng như vậy (hoặc tạo một đối tượng như vậy) thì chúng ta có thể nhận được tất cả chúng:
public void DestroyAllDontDestroyOnLoadObjects() {
var go = new GameObject("Sacrificial Lamb");
DontDestroyOnLoad(go);
foreach(var root in go.scene.GetRootGameObjects())
Destroy(root);
}
Bạn có thể tránh việc tạo một đối tượng hy sinh mỗi khi bạn cần thao tác trên danh sách các đối tượng này bằng cách tham chiếu một đối tượng như vậy mà bạn biết bạn sẽ luôn tồn tại (giả sử, đối tượng người quản lý mà chính tập lệnh này cư trú) hoặc bằng cách thực hiện nghi thức hiến tế một lần đầu khi chạy và lưu trữ một tham chiếu đến cảnh để sử dụng từ đó trở đi (trong các thử nghiệm của tôi, nó vẫn còn hiệu lực ngay cả sau khi tất cả các đối tượng của nó đã bị phá hủy và các đối tượng mới được đánh dấu DDOL)
Lưu ý rằng theo các tài liệu, thủ thuật này sẽ không hoạt động trong một trò chơi được xây dựng :
Bạn không có quyền truy cập vào cảnh DontDestroyOnLoad và nó không có sẵn trong thời gian chạy.
Cố gắng truy cập cảnh này sẽ ném một ngoại lệ phàn nàn rằng cảnh đó không hợp lệ.
Nếu sự hy sinh theo nghi thức làm bạn đau bụng (với lý do chính đáng, tôi sẽ nói) hoặc nếu bạn cần điều này trong thời gian chạy trong một trò chơi được xây dựng , một cách tiếp cận thông thường hơn sẽ là giới thiệu một DontDestroyOnLoadManager như thế này:
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();
}
}
Sau đó, bạn có thể thay thế bất kỳ trường hợp DontDestroyOnLoad(someObject)
nào khác trong cơ sở mã của bạn bằng someObject.DontDestroyOnLoad()
(ở đây tôi đang sử dụng một phương thức mở rộng để giữ cho nó ngắn gọn, nhưng bạn cũng có thể gọi nó một cách rõ ràng thông qua lớp người quản lý của bạn). Việc này kết thúc DontDestroyOnLoad riêng và cũng thực hiện việc ghi sổ cần thiết để tìm tất cả các đối tượng đó sau này. Nhược điểm là nếu bạn có các tập lệnh & plugin bên thứ 3 bổ sung gọi DontDestroyOnLoad, bạn cần sửa đổi chúng để được hệ thống này theo dõi.