Layar pemuatan halus antar adegan

14

Saya membuat layar pemuatan untuk menampilkan animasi pemuatan saat adegan berikutnya sedang dimuat. Saya memuat adegan berikutnya secara tidak sinkron dengan:

yield return SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive);

Dan juga diatur Application.backgroundLoadingPriority = ThreadPriority.Low;, tetapi perilaku masih sama dengan beban level biasa.

Apakah saya melewatkan sesuatu?

Perilaku yang diharapkan:

  • Keluar level, dan menghilang.
  • Layar memuat muncul.
  • Setelah pemuatan selesai, fade loading screen out.
  • Pudar di adegan selanjutnya.

Apa yang terjadi:

  • Keluar level, dan menghilang.
  • Layar memuat muncul, beku
  • Tiba-tiba pemandangan baru memudar.

Setelah pemuatan dimulai, gim ini akan macet, seperti dengan pemuatan adegan reguler.

Saya membaca bahwa Anda harus mengatur allowSceneActivation = false, sehingga Anda dapat memudar layar pemuatan, dan kemudian mengaturnya trueuntuk membiarkan persatuan selesai memuat, tetapi ini selesai membekukan permainan saya, seperti operasi async tidak pernah selesai memuat.

Leo
sumber
Saya punya masalah ini dan tidak menemukan apa pun di sini. Setelah googling saya menemukan apa yang menyebabkan masalah ini. Saya memutuskan untuk mempostingnya di sini sehingga orang lain dapat menemukan jawabannya dengan mudah. Harap beri tahu saya jika Anda ingin menambahkan beberapa peningkatan pada jawaban / pertanyaan saya. Terima kasih!
Leo

Jawaban:

18

Saat Anda memuat adegan dengan SceneManager.LoadSceneAsync() sebenarnya ada dua hal yang terjadi:

  • GameObjects adegan dimuat ke dalam memori.
  • Kemudian seluruh adegan diaktifkan. Semua panggilan balik Awake () dan Start () akan dipanggil untuk objek-objek dalam adegan.

Langkah kedua, mengaktifkan adegan, adalah apa yang sebenarnya membekukan persatuan, karena persatuan menjalankan semua panggilan balik inisialisasi dalam skrip Anda dalam satu siklus tunggal.

Memang pengaturan SceneManager.LoadSceneAsync().allowSceneActivationuntuk falsemembuat operasi async hanya menyelesaikan langkah pertama dari proses, dan akan menunggu sampai diatur ketrue untuk memulai bagian kedua dari proses.

Tetapi jika Anda mengatur allowSceneActivationuntuk falsedan hasil di callback seperti ini, Anda akan membekukan permainan Anda untuk selamanya:

AsyncOperation AO = SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive); 
AO.allowSceneActivation = false;
yield return AO;

//Fade the loading screen out here

AO.allowSceneActivation = true;

Mengapa? Karena Anda memberi tahu operasi Async untuk tidak melanjutkan dengan langkah kedua pemuatan adegan, sehingga operasi tidak akan pernah selesai.

Jika Anda ingin tahu kapan bagian pertama dari operasi siap, untuk kemudian melanjutkan dengan yang kedua, Anda harus bergantung AsyncOperation.progress. Nilai ini akan berhenti 0.9fsekaligus menungguallowSceneActivation bendera.

Seharusnya seperti ini:

AsyncOperation AO = SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive); 
AO.allowSceneActivation = false;
while(AO.progress < 0.9f)
{
    yield return null
}

//Fade the loading screen out here

AO.allowSceneActivation = true;

Jika Anda ingin aktivasi adegan tidak membekukan game Anda, maka Anda harus menjaga agar panggilan balik Awake and Start Anda menjadi minimun, dan inisialisasi skrip Anda dalam coroutine melalui beberapa siklus.

Leo
sumber
0

Saya memiliki masalah yang sama persis di Unity 5.6, dan sudah mencoba menambahkan dalam pernyataan hasil. Itu adalah LoadSceneAsync sendiri yang memblokir utas utama Unity dan mencegah adegan saat ini dengan baik menunjukkan setiap kemajuan pemuatan.

Sepertinya itu adalah bug di Unity sejauh yang saya tahu. Ketika adegan saya kurang kompleks, kode saya bekerja dengan baik, transisi mulus Setelah itu menjadi lebih besar, Unity memblokir utas selama sekitar 6 detik, sementara permainan duduk sebagai 'tidak merespons' meskipun operasi seharusnya "async"

Cara saya memecahkan masalah ini adalah dengan melihat pencahayaan saya. Ada bug besar di masa lalu dengan pencahayaan dan fitur ini. Jadi saya memeriksa objek saya, dan menemukan saya mendapat sorotan pada satu objek (meskipun dinonaktifkan ...)

Saya menghapus sorotan, dan hore! Adegan memuat async dengan benar! Tidak mengunci!

Lord of the Stack
sumber
Sebelum pengeditan, pos ini sebenarnya tidak menawarkan solusi untuk masalah tersebut. Tidak apa-apa sekarang Anda telah menambahkan perbaikan, tetapi di masa depan jika Anda ingin mengatakan "Saya mengalami masalah ini juga" Anda tidak boleh menggunakan jawaban untuk tujuan itu. Menghasilkan sedikit perwakilan akan memungkinkan Anda mengomentari posting yang ada, atau memberi hadiah pada pertanyaan untuk mendorong jawaban baru.
DMGregory