ดูคำตอบนี้ด้วย
มีวิธีการทั่วไปสองวิธีในการใช้Lerp:
1. การผสมเชิงเส้นระหว่างจุดเริ่มต้นและจุดสิ้นสุด
progress = Mathf.Clamp01(progress + speedPerTick);
current = Mathf.Lerp(start, end, progress);
นี่เป็นรุ่นที่คุณคุ้นเคยมากที่สุด
2. ความง่ายในการอธิบายต่อเป้าหมาย
current = Mathf.Lerp(current, target, sharpnessPerTick);
โปรดทราบว่าในรุ่นนี้currentค่าจะปรากฏเป็นทั้งเอาต์พุตและอินพุต มันแทนที่startตัวแปรดังนั้นเราจึงเริ่มต้นจากทุกที่ที่เราย้ายไปยังการปรับปรุงล่าสุด นี่คือสิ่งที่ให้Lerpหน่วยความจำรุ่นนี้จากเฟรมหนึ่งไปอีกเฟรมหนึ่ง จากนี้ย้ายจุดเริ่มต้นเราแล้วจากนั้นย้ายส่วนของระยะทางที่ไปทางtargetdictated โดยsharpnessพารามิเตอร์
พารามิเตอร์นี้ไม่มาก "ความเร็ว" อีกต่อไปเพราะเราเข้าใกล้เป้าหมายในนักปราชญ์เหมือนแฟชั่น ถ้าsharpnessPerTickเป็น0.5เช่นนั้นในการอัปเดตครั้งแรกเราจะย้ายไปครึ่งทางเพื่อบรรลุเป้าหมายของเรา จากนั้นในการอัพเดทครั้งต่อไปเราจะเลื่อนระยะทางที่เหลืออีกครึ่งหนึ่ง (ดังนั้นหนึ่งในสี่ของระยะทางเริ่มต้นของเรา) จากนั้นเราก็จะย้ายอีกครึ่งหนึ่ง ...
สิ่งนี้จะช่วยให้ "ความง่ายในการอธิบาย" ซึ่งการเคลื่อนที่นั้นรวดเร็วเมื่ออยู่ห่างจากเป้าหมายและค่อยๆช้าลงเมื่อเข้าใกล้ asymptotically (แม้ว่าจะมีจำนวนความแม่นยำที่ไม่มีที่สิ้นสุด เข้าใกล้พอ) มันยอดเยี่ยมสำหรับการไล่ล่าค่าเป้าหมายที่เคลื่อนไหวหรือการป้อนข้อมูลที่มีเสียงรบกวนให้เรียบโดยใช้ " ค่าเฉลี่ยเคลื่อนที่แบบเอ็กซ์โปเนนเชียล" โดยปกติจะใช้sharpnessPerTickพารามิเตอร์ขนาดเล็กมากเช่น0.1หรือเล็กกว่า
แต่คุณพูดถูกมีข้อผิดพลาดในลิงค์ upvote ที่คุณตอบ มันไม่ถูกต้องสำหรับdeltaTimeวิธีที่ถูกต้อง นี่เป็นข้อผิดพลาดทั่วไปมากเมื่อใช้รูปแบบLerpนี้
รูปแบบแรกของLerpคือเชิงเส้นดังนั้นเราจึงสามารถปรับความเร็วเชิงเส้นได้โดยการคูณด้วยdeltaTime:
progress = Mathf.Clamp01(progress + speedPerSecond * Time.deltaTime);
// or progress = Mathf.Clamp01(progress + Time.deltaTime / durationSeconds);
current = Mathf.Lerp(start, end, progress);
แต่การผ่อนคลายแบบเอ็กซ์โปเนนเชียลของเราไม่ใช่แบบเชิงเส้นดังนั้นเพียงแค่คูณsharpnessพารามิเตอร์ของเราด้วยdeltaTimeจะไม่ทำให้การแก้ไขเวลาถูกต้อง สิ่งนี้จะปรากฏเป็นผู้ตัดสินในการเคลื่อนไหวหากอัตราเฟรมของเราผันผวนหรือการเปลี่ยนแปลงของความคมชัดที่ผ่อนคลายหากคุณเปลี่ยนจาก 30 เป็น 60 อย่างสม่ำเสมอ
แต่เราจำเป็นต้องใช้การแก้ไขเลขชี้กำลังสำหรับความง่ายในการอธิบายของเรา:
blend = 1f - Mathf.Pow(1f - sharpness, Time.deltaTime * referenceFramerate);
current = Mathf.Lerp(current, target, blend);
นี่referenceFramerateเป็นเพียงค่าคงที่ที่ต้องการ30เก็บหน่วยให้sharpnessเหมือนกับที่เราใช้ก่อนที่จะแก้ไขเวลา
มีข้อผิดพลาดที่พิสูจน์ได้อีกข้อหนึ่งในรหัสนั้นซึ่งใช้Slerp- การแก้ไขเชิงเส้นทรงกลมมีประโยชน์เมื่อเราต้องการอัตราการหมุนที่สอดคล้องกันตลอดการเคลื่อนไหวทั้งหมด แต่ถ้าเราจะใช้การแจกแจงแบบไม่เป็นเชิงเส้นตรงนั้นLerpจะให้ผลที่ไม่สามารถแยกแยะได้และมันก็ถูกกว่า ;) Quaternions lerp ดีกว่าเมทริกซ์ทำดังนั้นนี่จึงเป็นการทดแทนที่ปลอดภัย