Utworzyłem ekran ładowania, aby wyświetlać animację ładowania podczas ładowania następnej sceny. Następną scenę ładuję asynchronicznie za pomocą:
yield return SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive);
I również ustawione Application.backgroundLoadingPriority = ThreadPriority.Low;
, ale zachowanie jest nadal takie samo jak zwykłe obciążenie poziomu.
Czy coś brakuje?
Oczekiwane zachowanie:
- Wyjdź z poziomu i wycisz.
- Pojawi się ekran ładowania.
- Po zakończeniu ładowania zniknij ekran ładowania.
- Zanikaj w następnej scenie.
Co się dzieje:
- Wyjdź z poziomu i wycisz.
- Zostanie wyświetlony ekran ładowania, zamrożony
- Nagle pojawia się nowa scena.
Po rozpoczęciu ładowania gra po prostu zawiesza się, jak w przypadku zwykłego ładowania sceny.
Przeczytałem, że musisz ustawić allowSceneActivation = false
, abyś mógł wyłączyć ekran ładowania, a następnie ustawić go tak, true
aby jedność zakończyła ładowanie, ale to całkowicie zawiesza moją grę, tak jakby operacja asynchroniczna nigdy się nie kończy.
Odpowiedzi:
Kiedy wczytujesz scenę, w
SceneManager.LoadSceneAsync()
rzeczywistości dzieją się dwie rzeczy:Drugi krok, włączenie sceny, jest tym, co faktycznie zamraża jedność, ponieważ jedność uruchamia wszystkie wywołania inicjujące w twoich skryptach w jednym cyklu.
Rzeczywiście ustawienie
SceneManager.LoadSceneAsync().allowSceneActivation
tofalse
spowoduje, że operacja asynchroniczna zakończy tylko pierwszy krok procesu, i poczeka, ażtrue
rozpocznie się druga część procesu.Ale jeśli ustawisz
allowSceneActivation
sięfalse
i rentowność zwrotnego jak ta, można zamrozić swoją grę na dobreDlaczego? Ponieważ mówisz operacji Async, aby nie kontynuowała drugiego kroku ładowania sceny, więc operacja nigdy nie zostanie zakończona.
Jeśli chcesz wiedzieć, kiedy pierwsza część operacji jest gotowa, aby przejść do drugiej, musisz polegać
AsyncOperation.progress
. Ta wartość zatrzyma się0.9f
natychmiast po oczekiwaniu naallowSceneActivation
flagę.Powinno to być coś takiego:
Jeśli chcesz, aby aktywacja sceny nie zamroziła twojej gry, powinieneś ograniczyć wywołania Przebudź i Rozpocznij do minimum, a także zainicjować skrypty w sposób ciągły przez kilka cykli.
źródło
Miałem dokładnie ten sam problem w Unity 5.6 i już próbowałem dodać w deklaracjach dochodu. To właśnie LoadSceneAsync blokował główny wątek Unity i uniemożliwiał bieżącej scenie ładnie pokazujący postęp ładowania.
O ile wiem, wydaje się, że jest to błąd w Unity. Kiedy moja scena była mniej złożona, mój kod działał świetnie, płynne przejście. Gdy się powiększy, Unity zablokował wątek na około 6 sekund, przez cały czas gra nie reaguje, mimo że operacja ma być „asynchroniczna”
Rozwiązałem ten problem, patrząc na moje oświetlenie. W przeszłości wystąpiły ogromne błędy związane z oświetleniem i tą funkcją. Więc przejrzałem moje obiekty i odkryłem, że mam reflektor na jednym obiekcie (nawet jeśli był wyłączony ...)
Usunąłem reflektor i brawo! Scena ładuje się poprawnie asynchronicznie! Bez blokady!
źródło