FixedUpdate للفيزياء
جزء من قسم الفيزياء وأسلوب اللعب في رحلة Unity على Coddy. الدرس 4 من 71.
تحرّك Unity الأجسام بخطوات فيزيائية ثابتة مدتها 0.02 ثانية (Time.fixedDeltaTime)، بمعدل 50 مرة في الثانية، أيًّا كان معدل الإطارات. تعمل FixedUpdate() مباشرة قبل كل خطوة. أما Update() فتعمل مرة واحدة مع كل إطار مرسوم، وقد يحدث ذلك 30 أو 60 أو 144 مرة في الثانية: عند 144 إطارًا، لا تتضمن معظم الإطارات أي خطوة فيزيائية، وعلى حاسوب بطيء قد يحتوي إطار واحد على خطوتين.
وينتج عن ذلك قاعدتان. تُضاف القوة المضافة في Update() مرة واحدة لكل إطار، لذا يدفع الحاسوب الأسرع بقوة أكبر: أضف القوى المؤثرة بمرور الوقت في FixedUpdate(). كذلك، تكون GetKeyDown صحيحة لإطار واحد فقط؛ فإذا لم يتضمن ذلك الإطار خطوة فيزيائية، فلن ترصدها FixedUpdate() أبدًا، وسيضيع الضغط. لذا اقرأ الضغطات في Update()، واحتفظ بها في قيمة bool، ونفّذ الإجراء استجابةً لها في FixedUpdate(). يُدفع هذا القارب بريح ثابتة ويندفع جانبيًا عند النقر:
private bool dashQueued;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
dashQueued = true; // تذكّر النقرة
}
}
void FixedUpdate()
{
rb.AddForce(Vector3.forward * wind); // دفعة ثابتة في كل خطوة
if (dashQueued)
{
rb.AddForce(Vector3.right * 4f, ForceMode.Impulse);
dashQueued = false; // نقرة واحدة، اندفاعة واحدة
}
}من المهم تصفير قيمة bool بعد استخدامها: فلو بقيت true، لاندفع القارب في كل خطوة. ويمكن أيضًا إضافة دفعة لحظية واحدة مباشرةً من Update()، كما حدث مع قفزة الضفدع؛ لكن قيمة bool تجمع كل الدفعات في مكان واحد، بجوار القوى التي تعمل معها. تصف المفاتيح المضغوطة (GetKey، GetAxis) حالةً لا لحظةً عابرة، لذا يمكن لـFixedUpdate() قراءتها مباشرة. داخل FixedUpdate()، تعيد Time.deltaTime قيمة 0.02 الخاصة بالخطوة.
التحدي
سهلضع مهمتَي الزلاجة في الأساليب الصحيحة.
- انقل كتلتَي
ifالخاصتين بالسهمين منUpdate()إلىFixedUpdate(). - أضف
private bool hopPressed;. فيUpdate()، اجعل قيمتهtrueعندInput.GetKeyDown(KeyCode.Space). - في
FixedUpdate()، عندما تكون قيمةhopPressedمضبوطة، أضف قوة الدفع اللحظية، ثم اجعل قيمتهfalse.
اضغط «العب»: ستدفع الأسهم بالتساوي، وستؤدي كل ضغطة على Space إلى قفزة. ثم اضغط «تحقق».
جرّب بنفسك
using UnityEngine;
public class Sled : MonoBehaviour
{
public float push = 6f;
public float hop = 5f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKey(KeyCode.RightArrow))
{
rb.AddForce(Vector3.right * push);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
rb.AddForce(Vector3.left * push);
}
}
void FixedUpdate()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * hop, ForceMode.Impulse);
}
}
}
جميع دروس الفيزياء وأسلوب اللعب
1الجسم الصلب (Rigidbody)
الجاذبية والكتلةالدفع باستخدام AddForceالقفز باستخدام دفعةFixedUpdate للفيزياءالسرعة المتجهةالأجسام الحركيةمراجعة: منصة الإطلاق4الكوروتينات
InvokeInvokeRepeating, CancelInvokeأول Coroutine لكالحلقات داخل الكوروتيناتإيقاف الكوروتيناتمراجعة: العد التنازلي10المشروع: الهروب من الحلبة
الحلبةالصيادونتدرّب بنفسك: Playground لـ Unity