Menu
CoddyTech

العد التنازلي

الدرس 23 من 25 في دورة لعبة Unity: الدفاع عن الأبراج على Coddy.

بين الموجات، يبني اللاعب، ويُظهر عدٌّ تنازلي مقدار الوقت المتبقي. ويمكن للاعب المستعد استدعاء الموجة التالية مبكرًا باستخدام زر. الاستراحة عبارة عن حلقة في coroutine تُعيد null، لذا تعمل مرة واحدة في كل إطار: تعدّ الوقت تنازليًا، وتعرضه، وتنتهي عند نفاد الوقت أو عندما يطلب الزر بدء الموجة. لا يغيّر الزر سوى قيمة bool، وتقرأها الحلقة:

while (left > 0f && !skipRequested)
{
    // اعرض الثواني المتبقية، وابدأ العد التنازلي، وانتظر إطارًا واحدًا
}
skipRequested = false;

تعود قيمة bool إلى false بعد استخدامها، وإلا فستنتهي كل استراحة بعد الأولى فورًا. تقوم Mathf.CeilToInt بالتقريب إلى الأعلى، لذا فإن قراءة الوقت المتبقي البالغ 2.3 ثانية تكون 3. ينفّذ yield return StartCoroutine(Countdown()); العدّ التنازلي وينتظر حتى ينتهي.

challenge icon

التحدي

صعب

ابدأ العدّ التنازلي لكل موجة؛ يتيح لك زر استدعاؤها مبكرًا.

  1. في WaveSpawner، أضف countdownText (TMP_Text) وnextWaveButton (GameObject) كسِمتين متسلسلتين، وأضف private bool callNow; وpublic void CallNextWave() { callNow = true; }.
  2. استبدل عبارة التوقف بـ yield return StartCoroutine(Countdown());: أظهر الزر، وأثناء بقاء وقت وعدم كون callNow صحيحًا، اعرض Next wave in 8 بعد تقريب الرقم إلى الأعلى، في كل إطار.
  3. ثم أعد callNow إلى false، وامسح النص وأخفِ الزر.

اضغط «العب»: يتخطى زر الموجة التالية وقت الانتظار. ثم اضغط «تحقق».

جرّب بنفسك

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WaveSpawner : MonoBehaviour
{
    [SerializeField] private List<Wave> waves = new List<Wave>();
    [SerializeField] private Transform[] waypoints;
    [SerializeField] private float timeBetweenWaves = 8f;

    void Start()
    {
        StartCoroutine(RunWaves());
    }

    IEnumerator RunWaves()
    {
        for (int i = 0; i < waves.Count; i++)
        {
            yield return new WaitForSeconds(timeBetweenWaves);
            Debug.Log("Wave " + (i + 1));
            Wave wave = waves[i];
            for (int n = 0; n < wave.count; n++)
            {
                Enemy enemy = Instantiate(wave.enemy, waypoints[0].position, Quaternion.identity);
                enemy.waypoints = waypoints;
                yield return new WaitForSeconds(wave.spacing);
            }
        }
        Debug.Log("All waves sent");
    }
}

جميع دروس لعبة Unity: الدفاع عن الأبراج

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