Menu
CoddyTech
flag Ar iconالعربيةdown icon

FixedUpdate للفيزياء

جزء من قسم الفيزياء وأسلوب اللعب في رحلة Unity على Coddy. الدرس 4 من 63.

يحرّك 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

التحدي

سهل

للزلاجة على البحيرة المتجمدة مهمتان، وكلتاهما في الطريقة الخاطئة. تدفعها الأسهم في Update()، لذا تُدفَع بقوة أكبر على أجهزة الكمبيوتر الأسرع. ويجعلها مفتاح المسافة تقفز باستخدام دفعة في FixedUpdate()، لذا لا تؤدي بعض الضغطات إلى أي شيء.

  • انقل الدفع بالأسهم إلى FixedUpdate().
  • اقرأ ضغط مفتاح المسافة في Update() وخزّنه في bool باسم hopPressed؛ وفي FixedUpdate()، اجعلها تقفز عندما تكون قيمته صحيحة، ثم أعد تعيينه.

اضغط على Play وجرّب الأمرين، ثم اضغط على Check.

جرّب بنفسك

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);
        }
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

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