ฉันกำลังจะเขียนสิ่งนี้เป็นความคิดเห็น แต่มันจบลงด้วยการที่ค่อนข้างยืดยาวดังนั้นฉันจึงกลายเป็นคำตอบ
คำตอบปัจจุบันส่วนใหญ่จะถูกต้อง แต่บางสิ่งที่กล่าวมานั้นทำให้เข้าใจผิด / ผิด
โดยทั่วไปงานที่เกี่ยวข้องกับการเล่นเกมส่วนใหญ่จะเข้าUpdate
มา
ตัวอย่างเช่นคุณไม่ต้องการโพลสำหรับอินพุตFixedUpdate
(ไม่ใช่เพราะประสิทธิภาพ แต่เนื่องจากการโทรไม่ทำงานอย่างถูกต้อง) AI ตกอยู่ในเรือลำเดียวกัน
ฟิสิกส์ที่ได้รับการปรับปรุงอย่างต่อเนื่องเป็นงานที่เกี่ยวข้องกับเกมเท่านั้นที่FixedUpdate
ควรใช้ / ไม่ต่อเนื่องครั้งหนึ่งในขณะที่มีการโทรไปยังสิ่งที่ต้องการPhysics.Raycast
หรือแม้กระทั่งเป็นของในRigidbody.AddForce
Update
การกล่าวถึงของฉันRigidbody.AddForce
ดูเหมือนจะขัดกับสิ่งที่อาจเป็นนัยโดยเอกสารประกอบ แต่กุญแจคือต่อเนื่อง vs ไม่ต่อเนื่อง
เหตุผลหนึ่งที่ว่าทำไมขนาดใหญ่เพียงฟิสิกส์อย่างต่อเนื่องอยู่ในเป็นธรรมชาติที่แท้จริงของFixedUpdate
FixedUpdate
คำตอบอื่น ๆ ได้กล่าวถึงวิธีที่ FixedUpdate เรียกว่าที่ fixed interval, but that's slightly misleading. In reality, a script is passed a time in Time.deltaTime
/ Time.fixedDeltaTime
* ซึ่งไม่ตรงกับเวลาจริงระหว่างการโทร แต่เป็นการจำลองเวลาระหว่างการโทร
(* Time.deltaTime
และTime.fixedDeltaTime
เป็นค่าเดียวกันเมื่อถูกเรียกในFixedUpdate
[Unity สามารถบอกได้ว่าการเรียกปัจจุบันไปยังTime.deltaTime
ต้นกำเนิดในระหว่างFixedUpdate
และส่งคืนTime.fixedDeltaTime
])
ธรรมชาติแบบเดียวกับที่ไม่สามารถเรียกว่าในลักษณะคงที่เนื่องจากประสิทธิภาพที่แตกต่างกันไม่สามารถUpdate
FixedUpdate
ความแตกต่างที่สำคัญคือแต่ละเฟรมหากFixedUpdate
ยังไม่ได้รับการเรียกบ่อยพอที่จะเฉลี่ยออกไปในช่วงเวลาที่ถูกต้องระหว่างการโทรก็จะได้รับการเรียกหลายครั้ง (หรือไม่ได้เรียกว่าค่าเฉลี่ยสูงเกินไป) นี่คือสิ่งที่เอกสารในคำสั่งการดำเนินการอ้างถึงโดยบอกว่า FixedUpdate สามารถเรียกได้หลายครั้งต่อเฟรม:
... FixedUpdate: FixedUpdate มักถูกเรียกบ่อยกว่าการอัพเดท สามารถเรียกหลายครั้งต่อเฟรมหากอัตราเฟรมต่ำและอาจไม่สามารถเรียกระหว่างเฟรมได้เลยหากอัตราเฟรมสูง ...
สิ่งนี้ไม่ได้ส่งผลกระทบต่อฟิสิกส์เนื่องจากลักษณะของส่วนที่เหลือของคำสั่งการดำเนินการและเครื่องยนต์ แต่สิ่งใดก็ตามที่คุณใส่เข้าไปFixedUpdate
จะได้รับผลกระทบและจะทำให้เกิดปัญหา
ตัวอย่างเช่นหากคุณใส่การประมวลผล AI ภายในFixedUpdate
ไม่มีเหตุผลที่จะถือว่า AI จะไม่ข้ามการอัปเดตสำหรับหลายเฟรมในหนึ่งแถว นอกจากนี้ในแต่ละครั้ง `FixedUpdate จะตกหล่น AI ของคุณจะอัปเดตหลายครั้งในเฟรมเดียวก่อนที่สิ่งต่าง ๆ เช่นฟิสิกส์และอินพุต / การเคลื่อนไหวของผู้เล่นจะถูกประมวลผลซึ่งเป็นการประมวลผลที่สิ้นเปลืองน้อยที่สุด เพื่อติดตามข้อบกพร่องและพฤติกรรมที่ผิดปกติ
หากคุณต้องการที่จะทำบางสิ่งบางอย่างที่คงใช้วิธีการอื่น ๆ ช่วงเวลาความสามัคคีให้เช่นและCoroutines
InvokeRepeating
และบันทึกย่อขนาดเล็กบนTime.deltaTime
และเวลาที่จะใช้:
วิธีที่ง่ายที่สุดในการอธิบายถึงผลกระทบของการ Time.deltaTime คือมันเปลี่ยนแปลงตัวเลขจากหน่วยต่อเฟรมไปยังหน่วยต่อวินาที ตัวอย่างเช่นถ้าคุณมีสคริปต์กับสิ่งที่ต้องการtransform.Translate(Vector3.up * 5)
ใน Update คุณกำลังหลักย้ายแปลงในอัตรา 5 เมตรต่อกรอบ นั่นหมายความว่าถ้าอัตราเฟรมต่ำการเคลื่อนไหวก็จะช้าลงและถ้าอัตราเฟรมสูงการเคลื่อนไหวก็จะเร็วขึ้น
ถ้าคุณใช้รหัสเดียวกันกับที่และเปลี่ยนเป็นtransform.Translate(Vector3.up * 5 * Time.deltaTime)
วัตถุที่จะถูกย้ายไปอยู่ในอัตรา 5 เมตรต่อวินาที นั่นหมายความว่าไม่ว่าจะเป็นอัตราเฟรมวัตถุจะเคลื่อนที่ 5 เมตรทุกวินาที (แต่ยิ่งช้าลงอัตราเฟรมจะเพิ่มขึ้นการเคลื่อนไหวของวัตถุจะยิ่งดีขึ้นเนื่องจากมันยังคงเคลื่อนที่เท่าเดิมทุก ๆ สิบวินาที)
โดยทั่วไปคุณต้องการให้การเคลื่อนไหวของคุณเป็นต่อวินาที ด้วยวิธีนี้ไม่ว่าคอมพิวเตอร์ของคุณจะมีความเร็วเท่าใดฟิสิกส์ / การเคลื่อนไหวของคุณจะทำงานในลักษณะเดียวกันและคุณจะไม่มีข้อผิดพลาดแปลก ๆ โผล่ขึ้นมาบนอุปกรณ์ที่ช้ากว่า
FixedUpdate
และมีจุดในการใช้มันไม่มี เนื่องจากสิ่งที่ฉันกล่าวถึงข้างต้นคุณจะได้รับค่าเดียวกันทุกการโทร (ค่าการอัปเดตการตั้งเวลาคงที่) และมันจะไม่ทำอะไรกับค่าของคุณ การเคลื่อนไหว / ฟิสิกส์ที่นิยามไว้FixedUpdate
จะมีหน่วยเป็นวินาทีต่อวินาทีดังนั้นคุณไม่ต้องการมัน