ทำไม Unity ใช้ภาพสะท้อนเพื่อรับวิธีการอัพเดต


12

ทำไมสามัคคีสะท้อนการใช้เพื่อการเข้าถึงMonoBehaviourวิธีการเช่นข้อความAwake, Update, Start, ... ?

การใช้ภาพสะท้อนจะไม่ช้าหรือไม่ ทำไมไม่ได้ใช้ประโยชน์จากวิธีการอื่น ๆ เช่นTemplate Method? มันสามารถนิยามเมธอดเป็นนามธรรมในMonoBehaviourคลาสฐานและบังคับให้คลาสย่อยนำไปใช้

คำตอบ:


20

มันไม่ได้

วิธีที่เรียกว่าการอัปเดต

ไม่ความเป็นเอกภาพไม่ได้ใช้ System.Reflection เพื่อค้นหาวิธีเวทย์มนตร์ทุกครั้งที่เรียกมัน

แต่ในครั้งแรกที่มีการเข้าถึง MonoBehaviour ของประเภทที่กำหนดสคริปต์พื้นฐานจะถูกตรวจสอบผ่านการรันไทม์ของสคริปต์ (Mono หรือ IL2CPP) ไม่ว่าจะมีวิธีการทางเวทมนตร์ที่กำหนดไว้หรือไม่ก็ตาม หาก MonoBehaviour มีวิธีการเฉพาะจะถูกเพิ่มลงในรายการที่เหมาะสมตัวอย่างเช่นหากสคริปต์มีวิธีการอัปเดตที่กำหนดไว้จะถูกเพิ่มเข้าไปในรายการสคริปต์ที่จำเป็นต้องอัปเดตทุกเฟรม

ในระหว่างเกม Unity จะวนซ้ำผ่านรายการเหล่านี้และดำเนินการตามวิธีการ - ง่าย ๆ นี่คือสาเหตุที่ไม่สำคัญว่าวิธีการอัปเดตของคุณเป็นแบบสาธารณะหรือแบบส่วนตัว

สำหรับเหตุผลที่ทำแบบนี้ฉันจะส่งต่อคุณ (ผู้อ่าน) ไปยังคำตอบของ DMGregoryซึ่งทำให้ความสมดุลของสองสิ่งแข่งขัน:

  1. การเพิ่มประสิทธิภาพการปฏิบัติงาน
  2. ความง่ายในการใช้ประโยชน์จากนักพัฒนาใหม่

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

การแก้ปัญหาน่าจะดีที่สุดที่สามารถทำได้ภายในข้อ จำกัด ทั้งสองนี้ หรืออย่างน้อยสิ่งที่ดีที่สุดที่ทีม Unity dev สามารถทำได้ในเวลานั้น เราอาจไม่มีทางรู้


2
tl; dr กระบวนการเดียวกัน, แตกต่าง, API ที่เร็วขึ้น แต่ทำไมพวกเขาถึงไม่เลือกวิธีอื่นตามที่ OP ถาม
wondra

10
เราไม่ควรปฏิเสธความเป็นไปได้ของเหตุผล "การออกแบบที่ไม่ดี" แบบเก่า หลังจากการเปิดตัวของ C # แหล่งรหัสผู้ใช้พบตันของความผิดพลาดและการตัดสินใจในการออกแบบไม่ได้อธิบาย gamedevs บางคนในที่สุดก็สามารถเข้าใจพฤติกรรมที่ไม่คาดคิดเหล่านั้นพวกเขากำลังต่อสู้กับเป็นเวลาหลายปี
Exerion

ด้านเทคนิคนอกเหนือจากนี้เป็นสิ่งแรกที่ผู้เรียนใหม่ได้เรียนรู้ดังนั้นจะต้องเพิ่มหรือข้ามได้ง่าย
Nikaas

6
อาจมีเหตุผลทางประวัติศาสตร์สำหรับการออกแบบนี้ ความสามัคคีเริ่มต้นด้วยภาษาสคริปต์ของพวกเขาเองซึ่งพวกเขาก็ค่อย ๆ เลิกชอบ C # มันเป็นธรรมดาที่พวกเขาต้องการใช้รูปแบบเดิม ๆ ต่อไปแม้ว่ามันจะเป็นการโกงเล็กน้อย
ฟิลิปป์

3
ฉันคิดว่าเราสามารถตอบได้อย่างมีประโยชน์ "ความสามัคคีทำให้สำเร็จโดยวิธีนี้" - เช่น อะไรคือข้อได้เปรียบเหนือคอลเลกชันของวิธีสาธารณะที่เป็นนามธรรมที่ทุกคนต้องนำไปใช้ เราไม่สามารถตอบ "สิ่งที่สามัคคีกำลังคิดอยู่" แต่เราสามารถจัดการ "ทำไมวิธีนี้มีประโยชน์กับผู้ใช้งานของเครื่องยนต์"
DMGregory

10

มันสามารถนิยามเมธอดเป็นนามธรรมในคลาสพื้นฐานของโมโนเบเฮวิโอและบังคับให้คลาสย่อยใช้มัน

ข้อดีอย่างหนึ่งของระบบที่ Unity ใช้คือคุณไม่จำเป็นต้องติดตั้งข้อความ MonoBehaviour ทุกข้อความซึ่งมีมากกว่า 60ข้อความ

โดยปกติแล้วเราเพียงแค่ต้องการวิธีการเหล่านี้เพียงเล็กน้อย เนื่องจากบางตัวมีความเฉพาะเจาะจงกับฟิสิกส์ 2D / 3D บางอย่างที่เป็นเอกลักษณ์ของกล้องหรือระบบอนุภาคจึงไม่น่าเป็นไปได้สูงที่สคริปต์ใดบทหนึ่งจะต้องการทั้งหมดของพวกเขา

เมื่อออกจากข้อความที่เราไม่ต้องการใช้งานเราสามารถส่งสัญญาณให้รันไทม์ได้อย่างชัดเจนว่า "ไม่ต้องโทรไปที่ OnCollisionStay2D บนวัตถุนี้ - ฉันไม่ต้องการ"

นี่อาจเป็นชัยชนะที่มีประสิทธิภาพ ตอนนี้เครื่องยนต์สามารถกรองรายการสั้น ๆ เพื่อเรียกการอัปเดตเฉพาะวัตถุ ~ 20 ในฉากของฉันที่ต้องใช้ตรรกะการปรับปรุงที่กำหนดเองทุกเฟรมและไม่ใช่วัตถุ ~ 200 ทั้งหมดที่ประกอบฉากทั้งหมดหรือตอบสนองต่อเหตุการณ์ฟิสิกส์เท่านั้น


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

4
@Battle สิ่งที่คุณอธิบายนั้นสอดคล้องกับลิงก์ที่ Draco18s อ้างอิงจากปี 2015 และฉันสงสัยว่ามันยังคงเป็นจริง ความสามารถในการคงไว้ซึ่งวิธีการอัพเดตที่ไม่ได้กำหนดบนวัตถุหลายพันรายการนั้นเป็นสิ่งที่ช่วยให้การเพิ่มประสิทธิภาพนี้ทำงานได้อย่างแม่นยำ หาก MonoBehaviour ทุกคนมีวิธีการอัปเดตที่กำหนดไว้ผ่านคลาสฐานนามธรรมตามที่อธิบายไว้ในส่วนของคำถามที่ฉันยกมาเราจะไม่มีความสามารถในการ จำกัด การเรียกการอัปเดตเป็นรายการซ้ำของผู้จัดการ โปรดทราบว่าคำถาม & คำตอบนี้ไม่ได้กล่าวว่า แต่วิธีการในปัจจุบันเท่านั้นที่จะได้รับประโยชน์
DMGregory

ฉันเข้าใจแล้วใช่มั้ย ขอบคุณสำหรับคำตอบ!
ต่อสู้

@ การต่อสู้มันยังคงเป็นจริง ในขณะที่สิ่งที่ Unity ทำนั้นมีประสิทธิภาพมากกว่าทางเลือก แต่ก็ยังมีค่าใช้จ่ายมากกว่าการเรียกใช้ฟังก์ชันปกติ
Draco18 ไม่ไว้วางใจ SE

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