DontDestroyOnLoad nie do końca działa.

0

Witam.
Mam pewien problem, który zdaje się nie był poruszany nigdzie na żadnym forum.
Otóż DontDestroyOnLoad działa dobrze, nie niszczy obiektu, jednakże skrypt, który jest do niego dołączony wykonuje się po załadowaniu sceny.
Nie ważne czy robię LoadScene, czy loadSceneAsync, czy LoadSceneAsync Additive...
Zawsze po wczytaniu sceny wykonuje się Awake, Start i pozostałe.
Czy da radę jakoś tego uniknąć?
Singleton mam z pierwszej sceny a w kolejnej ten sam plik, z tym samym skryptem chce na nowo przypisać Singletona i pokazuje mi stosowny komunikat.
(SendToTerminal to pokazuje na konsoli informacje)
(Kod w Awake)

        if (!instance)
        {
            DontDestroyOnLoad(this.gameObject); // Póki działa gra to consola będzie działać
            instance = this.gameObject.GetComponent<TerminalCommand>();
        }
        else
        {
            Destroy(this.gameObject.GetComponent<TerminalCommand>());
            SendToTerminal("Game try create more than one Terminal Commands in scene.\n" +
                "Game remove Terminal component from object: " + this.name, MesseageType.Warring, this.gameObject);
        }
0

Dlaczego w 8 linijce robisz Destroy komponentu TerminalCommand?
Powinieneś zniszczyć this.gameObject.

Poza tym ja dla pewności bym napisał if (instance == null) zamiast if (!instance).

I po co używasz GetComponent()?
this to powinien być Twój komponent, więc w linii 4 piszesz instance = this;

0
Spine napisał(a):

Dlaczego w 8 linijce robisz Destroy komponentu TerminalCommand?
Powinieneś zniszczyć this.gameObject.

Niszczę tylko komponent ten a obiekt ma zostać.

Poza tym ja dla pewności bym napisał if (instance == null) zamiast if (!instance).

Przecież to jest to samo.

Spine napisał(a):

I po co używasz GetComponent()?
this to powinien być Twój komponent, więc w linii 4 piszesz instance = this;

Moim komponentem do instance jest dany skrypt a nie gameobject.

Singleton ma być zabezpieczeniem na ewentualne użycie tego skryptu w innym obiekcie i scenie a nie na użycie tego samego obiektu w scenie.

0

A czy jak zapauzujesz i sobie zobaczysz w hierarchii, to wszystko jest okej?
Bo z tego co pamiętam to destroy najpierw sobie kolejkuje, a działa fizycznie dopiero na koniec klatki lub w kolejnej.
Czyli mogłoby być tak, że mimo, że skasowałeś komponent, to jeszcze zdążył się zrobić start
(awake na pewno, bo w nim robisz kasowanie).
Ustawienie zwykłego bool'a isDestroying i sprawdzanie go w starcie powinno rozwiązać problem.

A jeśli w hierarchii jest źle to sprawdź czy instance na pewno jest static

0

Instance na pewno jest static. Bardziej mnie martwi to że wykonuje się skrypt obiektu który był wczytany w poprzedniej scenie i jest DontDestroyOnLoad
Możliwe że kompilator rozpoznaje że obiekt ma być zniszczony, ponieważ jak w scenie którą wczytuje jest ten sam skrypt to tylko jedno ostrzeżenie pokazuje a komunikat w terminalu jest dwa razy napisany (debug warring jest w dołączone do skryptu SendToTerminal).
Jest jakiś sposób aby obiekt który jest DontDestroyOnLoad nie wykonywał pętli Start i Awake jak jest wczytywania kolejna scena?
To wygląda tak jakby ten obiekt był niszczony i jeszcze raz tworzony ponieważ wartości niestatyczne są null

0

No właśnie nie powinien już robić tego startu i awake, to nie jest normalne. Nigdy nie miałem takich problemów, z tym że: swoje singletony trzymam tylko na wejściowej scenie, do której nie wracam (jeszcze przed menu), a na kolejnych scenach już ich nie umieszczam.
Ale wracając do problemu: może gdzieś kasujesz parenta tego singletona z poprzedniej sceny? wtedy dontdestroy nie pomoże
jeszcze jeden pomysł: wrzuć tam private void OnDestroy() { Debug.log("XX"); }
i zobacz czy i kiedy sie wywoluje, i na którym

0

Ok, nie wiem dlaczego ale problem rozwiązał się sam. Wcześniej jak wczytywałem skrypt i jeden miałem w LoadScene (tak jak kolega to robi) a drugi we wczytywanej scenie dla testu czy wszytko działa i jak wcześniej skrypt Awake był wykonywany 3 razy, tak teraz 2 razy.
Taki OFT:
Pewnie większość o tym wie, albo sami zrobili terminal rodem z Quake, 7Days to Die itp. Do pobrania jest Tutaj0
Oczywiście za darmo.
Tak to pytanko takie. Jest gdzieś może tutaj na forum jakiś dział dla przydatnych narzędzi do Unity, C# czy innych języków?

0
tdx110 napisał(a):

Tak to pytanko takie. Jest gdzieś może tutaj na forum jakiś dział dla przydatnych narzędzi do Unity, C# czy innych języków?

Najbardziej zbliżony jest ten dział...
Co rozumiesz przez "przydatne narzędzia"?

A jeśli chodzi o Twój terminal, to można się obejść bez singletona na Scenie... Wystarczy zwykły prefab dodany do wszystkich scen (tak jak obecnie), który swoje dane zachowuje w jakimś statycznym obiekcie. I z tego obiektu ładuje dane po załadowaniu sceny.

0
Spine napisał(a):
tdx110 napisał(a):

A jeśli chodzi o Twój terminal, to można się obejść bez singletona na Scenie... Wystarczy zwykły prefab dodany do wszystkich scen (tak jak obecnie), który swoje dane zachowuje w jakimś statycznym obiekcie. I z tego obiektu ładuje dane po załadowaniu sceny.

Dokładnie to nie mój terminal, ale uznałem że jest przydatny to warto się nim podzielić.
Dodałem sam Singletona, ponieważ tworzy się on dopiero w Start, a Instance początkowych obiektów dodaje w Awake, wiec dlatego wczytywanie sceny zrobiłem.
Oczywiście musiałem także kilka linii kodu zmienić aby wszystko działało...

1 użytkowników online, w tym zalogowanych: 0, gości: 1