Menu
CoddyTech

الحلقات داخل الكوروتينات

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

تعمل الحلقة التي تحتوي على yield return على مدى إطارات عديدة، لأن كل دورة تتوقف مؤقتًا قبل التالية. باستخدام WaitForSeconds تكرر الحلقة شيئًا بإيقاع منتظم. يومض هذا المنبّه 3 مرات:

IEnumerator Flash()
{
    for (int i = 0; i < 3; i++)
    {
        lamp.enabled = true;
        yield return new WaitForSeconds(0.2f);
        lamp.enabled = false;
        yield return new WaitForSeconds(0.2f);
    }
}

باستخدام yield return null تنفذ الحلقة شيئًا صغيرًا في كل إطار إلى أن يتحقق شرطها، وهكذا تحرّك الدالة التعاونية شيئًا ما. يكبر هذا المنطاد، الذي مقياسه 1، بمقدار 0.5 في الثانية حتى يصل مقياسه إلى 2، ثم يعرض:

IEnumerator Inflate()
{
    while (transform.localScale.x < 2f)
    {
        transform.localScale += Vector3.one * 0.5f * Time.deltaTime;
        yield return null;
    }
    Debug.Log("Full");
}

يعمل Time.deltaTime هنا كما في Update(): تُستأنف الدالة التعاونية مرة واحدة في كل إطار، ولا يُنفذ السطر الذي يلي الحلقة إلا عند انتهاء الحلقة. من دون yield، تعمل الحلقة كلها ضمن إطار واحد ويمتلئ المنطاد دفعة واحدة. لا بأس باستخدام حلقة while (true) في دالة تعاونية ما دامت تتنازل عن التحكم في كل دورة؛ فمن دون ذلك، لن تعيد التحكم إلى الإطار أبدًا، وسيتجمد محرر Unity.

challenge icon

التحدي

سهل

اكتب Ride لكي تقوم البوابة برحلة كاملة واحدة.

  1. عيّن Vector3 up = down + Vector3.up * height;. أثناء while (transform.position != up)، حرّكها باستخدام Vector3.MoveTowards(transform.position, up, speed * Time.deltaTime) وyield return null;.
  2. سجّل Open، ثم yield return new WaitForSeconds(1f);.
  3. كرّر الحركة نزولًا إلى down بالطريقة نفسها، ثم سجّل Closed.

اضغط «العب» ثم اضغط على مفتاح المسافة: سترتفع البوابة، وتنتظر، ثم تُغلق. بعد ذلك اضغط «تحقق».

جرّب بنفسك

using System.Collections;
using UnityEngine;

public class Portcullis : MonoBehaviour
{
    public float speed = 1.5f;
    public float height = 3f;
    Vector3 down;

    void Start()
    {
        down = transform.position;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Ride());
        }
    }

    IEnumerator Ride()
    {
        // ارتفع بمقدار height من الوحدات بسرعة speed وسجّل Open، وانتظر 1 ثانية، ثم انزل مجددًا وسجّل Closed
        yield return null;
    }
}

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

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