CUSTOM COROUTINES !!!

unity3D_code

บทความในครั้งนี้ผู้เขียนคงต้องขอกราบขอบคุณงาม ๆ กับ blogs.unity3d และคุณ  ที่ได้นำความรู้ดี ๆ มามอบให้กับพวกเราได้ศึกษาและใช้งานกับ ” Custom coroutines “


Custom coroutines หรือก็คือ Class ” CustomYieldInstruction “ ที่ทำให้เราสามารถเพิ่ม Coroutine yield operations ได้ง่ายขึ้นมาก ๆ ดั่งตัวอย่างข้างล่างนี้

A real world example – A bugfix (ตัวอย่าง และ Bug ที่เจอ)
  • เพื่อน ๆ หลายคนคงทราบกันดี หรือไม่ทราบก็ตามว่ามี Bug อยู่ตัวหนึ่งใน UI Dropdown ของ Unity 5.2 ซึ่งเมื่อเราใช้ Time.timescale และเซ็ตค่ามันให้เป็น 0 เจ้า Dropdown มันจะทำงานเพียงครั้งเดียวเท่านั้น และจะทำงานไม่ได้อีกจนกว่าเราจะเซ็ตค่าของ Time.timescale ให้เป็นค่าที่ไม่เท่ากับ 0 โดยเมื่อตรวจสอบดูว่าผิดตรงไหน ก็ได้พบว่ามันมีปัญหาอยู่ในฟังก์ชั่น Show นั่นเอง2

    ปล. จาก Scrip ข้างบนนั้นเมื่อตรวจสอบแล้วพบว่า m_Dropdown ไม่เป็น null และมีการป้องกันไม่ให้ Dropdown ทำงาน

  • แสดงให้เห็นว่า  m_Dropdown นั้นถูกทำลาย หรือถูกลบค่าออกไป ซึ่งมันก็ถูกแล้วที่มันสมควรถูกทำลาย แต่เมื่อ timescale มีค่าเป็น 0 จะทำให้เงื่อนไขนี้ไม่เกิดขึ้น ลองดูฟังก์ชั่น destroy ข้างล่างนี้แล้วเพื่อน ๆ จะเห็นปัญหามากขึ้น

1

 

  • WaitForSeconds ถูกใช้ในการปรับเวลา ซึ่งหมายความว่า เมื่อเราบอกให้ WaitForSeconds ต้องรอเป็นเวลา 1 วินาที และ timescale มีค่าเป็น 0.5 นั่นจะส่งผลให้เราต้องรอถึง 2 วินาที (1 / 0.5 = 2) ดังนั้นหาก timescale เป็น 0 ก็หมายความว่า WaitForSeconds จะต้องรอไปเรื่อย ๆ จนกว่า timescale จะไม่เป็น 0 นั่นทำให้ Dropdown ไม่ถูกทำลายหลังจากที่ใช้ไปในครั้งแรก เพราะ WaitForSeconds ถูกทำงานไปก่อนแล้ว (ดั่ง Code ด้านบน)
The solution (วิธีแก้ปัญหา)
  • เราต้องรอโดยไม่ต้องไปยุ่งกับการปรับเวลา ซึ่งวิธีที่ดีที่สุดในตอนนี้ก็คือการใช้ Class WaitForSecondsRealtime  ตาม Code ข้างล่างต่อไปนี้เลย3ปล. การใช้งานข้างบนก็คล้าย ๆ WaitForSeconds แต่เราจะต้องเช็คผ่าน keepWaiting และต้องให้ส่งค่ากลับไปเป็น false เท่านั้นถึงจะจบการรอ
  • นี่ถือเป็นวิธีแก้ไขปัญหากับ Bug ที่เราเจอในตอนนี้4
  • นอกจากวิธีข้างบนแล้ว เรายังมี WaitUntil และ WaitWhile ในการทำกรณีนี้อีกด้วย สมมติว่าเราต้องการ 5 วินาที

5

แหล่งที่มา blogs.unity3d : CUSTOM COROUTINES