Menu
CoddyTech

הגל הבא

שיעור 17 מתוך 18 בקורס משחק Unity: הגנת מגדלים של Coddy.

בין הגלים השחקן בונה, וספירה לאחור מציגה כמה זמן נותר. שחקן שמוכן יכול להזניק את הגל הבא מוקדם באמצעות כפתור. ההפסקה היא לולאה בקורוטינה שמחזירה null, ולכן היא רצה פעם אחת בכל פריים: היא סופרת לאחור את הזמן שנותר, מציגה אותו ומסתיימת כשהזמן נגמר או כשהכפתור ביקש להזניק את הגל. הכפתור רק מגדיר ערך בוליאני, והלולאה קוראת אותו:

while (left > 0f && !skipRequested)
{
    // הצג את מספר השניות שנותרו, בצע ספירה לאחור, המתן לפריים אחד
}
skipRequested = false;

הערך הבוליאני מוגדר בחזרה ל-false אחרי השימוש בו, אחרת כל הפסקה אחרי הראשונה הייתה מסתיימת מיד. Mathf.CeilToInt מעגל כלפי מעלה, כך שכשנותרו 2.3 שניות מוצג 3, והספירה לאחור מציגה 1 לאורך כל השנייה האחרונה במקום 0. הספירה לאחור היא קורוטינה בפני עצמה, ו-yield return StartCoroutine(Countdown()); מפעיל אותה וממתין לסיומה לפני שלולאת הגלים ממשיכה.

ממשק המשתמש (HUD) מציג גם את מספר הגל. ה-spawner יודע אותו, ו-GameManager מציג אותו, ולכן ה-spawner מפעיל אירוע C#, WaveStarted, עם הגל ומספר הגלים. בניגוד לאירועים הסטטיים של האויבים, האירוע הזה שייך ל-spawner היחיד, ו-GameManager נרשם אליו דרך השדה שלו spawner.

challenge icon

אתגר

קשה
  1. ב־WaveSpawner, הוסיפו את השדות הסריאליים countdownText (מסוג TMP_Text) ו־nextWaveButton (מסוג GameObject), ואת public void CallNextWave(), שאותו הכפתור קורא כדי לבקש להתחיל את הגל מיד.
  2. החליפו את ההמתנה לפני כל גל בספירה לאחור, שמתבצעת באמצעות yield return StartCoroutine(Countdown());. בזמן שהיא מתבצעת, הכפתור מוצג והטקסט מציג Next wave in 8, כלומר את מספר השניות שנותרו בעיגול כלפי מעלה. הספירה מסתיימת כשהזמן נגמר או כשלוחצים על הכפתור; לאחר מכן הטקסט מתרוקן והכפתור מוסתר.
  3. הוסיפו את public event Action<int, int> WaveStarted, שמופעל כשגל מתחיל ומעביר את מספר הגל (החל מ־1) ואת מספר הגלים.
  4. ב־GameManager, הוסיפו את השדות הסריאליים spawner (מסוג WaveSpawner) ו־waveText (מסוג TMP_Text), הירשמו ל־WaveStarted, והציגו Wave 1/8.

ב־HUD מופיעים WaveText, CountdownText ו־NextWaveButton. לחצו על Play, בנו, והתחילו את הגל הראשון מוקדם, ואז לחצו על Check.

נסו בעצמכם

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 = 5f;

    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");
    }
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה משחק Unity: הגנת מגדלים