Menu
CoddyTech

طهّر الساحة

جزء من قسم هندسة الألعاب في Unity في رحلة Unity على Coddy. الدرس 55 من 64.

الحدث المعلَّم بـ static ينتمي إلى الصنف، لا إلى كائن واحد. يوجد حدث Enemy.Died واحد لكل عدو قد يوجد على الإطلاق، لذا يستطيع مولِّد الأعداء الاشتراك فيه باستخدام Enemy.Died += OnEnemyDied; قبل وجود أي عدو، ويُطلقه كل عدو مع تمرير نفسه كوسيط. الفكرة نفسها بصياغة C# عادية:

public class Coin
{
    public static event Action<Coin> Picked;

    public void Pick()
    {
        Picked?.Invoke(this);
    }
}

public class Purse
{
    private int coins;

    public Purse()
    {
        Coin.Picked += OnPicked;   // لا حاجة إلى Coin بعد
    }

    void OnPicked(Coin coin)
    {
        coins++;
    }
}

يمكن الوصول إلى حدث المثيل عبر كائن، مثل hero.Died؛ أما الحدث الساكن فيُوصَل إليه عبر اسم الصنف، مثل Coin.Picked. يستمر الحدث الساكن بعد زوال كل كائن، لذا ألغِ الاشتراك في OnDisable، وإلا فسيبقى مولِّد الأعداء المُتلف في قائمته.

challenge icon

التحدي

متوسط

اجعل كل موجة تنتظر حتى تخلو الساحة.

  1. في Enemy، أضف public static event Action<Enemy> Died; واستدعِ Died?.Invoke(this); مباشرةً قبل Destroy(gameObject);.
  2. في WaveSpawner، تتبّع عدد alive: أضف 1 مع كل عملية ظهور، واطرح 1 في دالة يضيفها OnEnable إلى Enemy.Died ويزيلها OnDisable.
  3. بعد ظهور موجة، انتظر ما دام alive > 0.

اضغط «العب» واهزم الموجة 1: ستأتي الموجة 2 بعد ثانيتين. ثم اضغط «تحقق».

جرّب بنفسك

using System.Collections;
using UnityEngine;

public class WaveSpawner : MonoBehaviour
{
    [SerializeField] private WaveSet waveSet;
    [SerializeField] private Transform[] spawnPoints;

    public int Wave { get; private set; }

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

    IEnumerator RunWaves()
    {
        while (true)
        {
            foreach (Wave wave in waveSet.waves)
            {
                Wave++;
                Debug.Log("Wave " + Wave);
                for (int i = 0; i < wave.count; i++)
                {
                    Transform point = spawnPoints[i % spawnPoints.Length];
                    Instantiate(wave.enemy, point.position, Quaternion.identity);
                    yield return new WaitForSeconds(wave.spacing);
                }
                yield return new WaitForSeconds(waveSet.restBetweenWaves);
            }
        }
    }
}

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

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