หน้าจอการโหลดที่ราบรื่นระหว่างฉาก


14

ฉันสร้างหน้าจอการโหลดเพื่อแสดงภาพเคลื่อนไหวขณะโหลดฉากถัดไป ฉันโหลดฉากถัดไปแบบอะซิงโครนัสด้วย:

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

และยังตั้งApplication.backgroundLoadingPriority = ThreadPriority.Low;ให้ แต่พฤติกรรมยังคงเหมือนเดิมกับการโหลดในระดับปกติ

ฉันพลาดอะไรไปรึเปล่า?

พฤติกรรมที่คาดหวัง:

  • ระดับทางออกและจางหายไป
  • หน้าจอกำลังโหลดปรากฏขึ้น
  • เมื่อโหลดเสร็จแล้วหน้าจอการโหลดจะจางหายไป
  • จางหายไปในฉากต่อไป

เกิดอะไรขึ้น:

  • ระดับทางออกและจางหายไป
  • หน้าจอโหลดปรากฏขึ้นเป็นน้ำแข็ง
  • ทันใดนั้นฉากใหม่ก็จางหายไป

เมื่อโหลดเริ่มเกมจะหยุดเช่นเดียวกับโหลดฉากปกติ

ฉันอ่านว่าคุณต้องตั้งค่าallowSceneActivation = falseเพื่อให้คุณสามารถจางหน้าจอการโหลดออกไปแล้วตั้งtrueให้เป็นอันหนึ่งอันเดียวกันให้เสร็จสิ้นการโหลด แต่การทำเช่นนี้จะทำให้เกมของฉันค้างเหมือนกับที่การดำเนินการ async ไม่เคยโหลดเสร็จ


ฉันมีปัญหานี้และไม่พบสิ่งใดที่นี่ หลังจาก googling ฉันพบสิ่งที่ทำให้เกิดปัญหานี้ ฉันตัดสินใจที่จะโพสต์ที่นี่เพื่อให้คนอื่นสามารถหาคำตอบได้อย่างง่ายดาย โปรดแจ้งให้เราทราบหากคุณต้องการปรับปรุงคำตอบ / คำถามของฉัน ขอบคุณ!
Leo

คำตอบ:


18

เมื่อคุณโหลดฉากที่SceneManager.LoadSceneAsync()มีสองสิ่งเกิดขึ้นจริง:

  • เกมวัตถุประสงค์ของฉากนั้นถูกโหลดลงในหน่วยความจำ
  • จากนั้นเปิดใช้งานฉากทั้งหมด การเรียกกลับทั้งหมด Awake () และ Start () จะถูกเรียกสำหรับวัตถุในฉาก

ขั้นตอนที่สองเปิดใช้งานฉากคือสิ่งที่จริงแล้วตรึงความสามัคคีเพราะความสามัคคีกำลังเรียกใช้การเรียกคืนเริ่มต้นทั้งหมดในสคริปต์ของคุณในรอบเดียว

อันที่จริงการตั้งค่าSceneManager.LoadSceneAsync().allowSceneActivationเพื่อfalseจะทำให้การดำเนินงาน async ให้เสร็จสมบูรณ์เพียงขั้นตอนแรกของกระบวนการและจะรอจนกว่าจะมีการตั้งค่าเพื่อtrueที่จะเริ่มต้นส่วนที่สองของกระบวนการ

แต่ถ้าคุณตั้งค่าallowSceneActivationการfalseและอัตราผลตอบแทนในการเรียกกลับเช่นนี้คุณจะหยุดเกมของคุณให้ดี:

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

//Fade the loading screen out here

AO.allowSceneActivation = true;

ทำไม? เนื่องจากคุณกำลังบอกให้การดำเนินการ Async ไม่ดำเนินการในขั้นตอนที่สองของการโหลดซีนภาพดังนั้นการดำเนินการจะไม่เสร็จสมบูรณ์

AsyncOperation.progressถ้าคุณต้องการที่จะรู้ว่าเมื่อส่วนแรกของการดำเนินงานที่มีความพร้อมไปแล้วดำเนินการอย่างใดอย่างหนึ่งที่สองคุณจะต้องพึ่งพา ค่านี้จะหยุด0.9fทันทีที่มันกำลังรอallowSceneActivationธง

มันควรเป็นแบบนี้:

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;

หากคุณต้องการให้การเปิดใช้งานฉากไม่ทำให้เกมค้างคุณควรโทรกลับไปยังจุดเริ่มต้นและจุดเริ่มต้นเพื่อย่อและเริ่มต้นสคริปต์ของคุณใน coroutine ผ่านหลายรอบ


0

ฉันมีปัญหาเดียวกันแน่นอนใน Unity 5.6 และได้ลองเพิ่มในข้อความประกาศผลตอบแทนแล้ว LoadSceneAsync นั้นเองที่บล็อกเธรดหลักของ Unity และป้องกันไม่ให้ฉากปัจจุบันแสดงความคืบหน้าในการโหลดอย่างชัดเจน

มันน่าจะเป็นบั๊กใน Unity เท่าที่ฉันจะบอกได้ เมื่อฉากของฉันซับซ้อนน้อยรหัสของฉันก็ใช้งานได้ดีและราบรื่น เมื่อมันมีขนาดใหญ่ขึ้น Unity บล็อกเธรดเป็นเวลาประมาณ 6 วินาทีขณะที่เกมอยู่ในสถานะ 'ไม่ตอบสนอง' แม้จะมีการดำเนินการตามที่คาดว่าจะเป็น "async"

วิธีที่ฉันแก้ไขปัญหาคือดูแสงของฉัน มีข้อบกพร่องมากมายในอดีตที่มีแสงสว่างและคุณสมบัตินี้ ดังนั้นฉันผ่านวัตถุของฉันและพบว่าฉันมีสปอตไลท์บนวัตถุหนึ่ง (แม้ว่ามันจะถูกปิดใช้งาน ... )

ฉันลบสปอตไลท์และไชโย! โหลด async อย่างเหมาะสม! ไม่มีการล็อค!


ก่อนการแก้ไขโพสต์นี้ไม่ได้เสนอวิธีแก้ไขปัญหา ไม่เป็นไรตอนนี้ที่คุณได้เพิ่มการแก้ไข แต่ในอนาคตหากคุณต้องการพูดว่า "ฉันมีปัญหานี้ด้วย" คุณไม่ควรใช้คำตอบสำหรับจุดประสงค์นั้น การรับตัวแทนเล็กน้อยจะช่วยให้คุณสามารถแสดงความคิดเห็นในโพสต์ที่มีอยู่หรือวางคำถามเพื่อสนับสนุนคำตอบใหม่
DMGregory
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.