Menu
CoddyTech

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 الخاصة بالخطوة.

challenge icon

التحدي

سهل

ضع مهمتَي الزلاجة في الأساليب الصحيحة.

  1. انقل كتلتَي if الخاصتين بالسهمين من Update() إلى FixedUpdate().
  2. أضف private bool hopPressed;. في Update()، اجعل قيمته true عند Input.GetKeyDown(KeyCode.Space).
  3. في 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);
        }
    }
}

جميع دروس الفيزياء وأسلوب اللعب

تدرّب بنفسك: Playground لـ Unity