الوصول إلى القاعدة
الدرس 3 من 18 في دورة لعبة Unity: الدفاع عن الأبراج على Coddy.
العدو الذي يصل إلى نقطة المسار الأخيرة يكون قد بلغ القاعدة: يخسر اللاعب أرواحًا ويرحل العدو. الأرواح تخص GameManager، الذي يعرضها على الشاشة. لا ينبغي أن يحتاج العدو إلى مرجع إلى GameManager للإبلاغ عن ذلك: فسرعان ما ستُنشأ الأعداء بالعشرات من قالب، ولا يمكن للقالب أن يشير إلى كائن في المشهد.
يحل الحدث الثابت الأمرين معًا. فهو يخص فئة Enemy، وليس عدوًا واحدًا، لذا يشترك GameManager فيه مرة واحدة ويتلقى إشعارات من كل عدو، بما في ذلك الأعداء الذين يُنشؤون لاحقًا. يطلق كل عدو الحدث ويمرر نفسه كوسيط، حتى يتمكن المستمع من معرفة نوع العدو الذي وصل. وتُبلغ عملة في لعبة منصات بالطريقة نفسها:
public class Coin : MonoBehaviour
{
public static event Action<Coin> Collected;
public int value = 1;
void OnTriggerEnter(Collider other)
{
Collected?.Invoke(this);
Destroy(gameObject);
}
}// ScoreBoard.cs
void OnEnable()
{
Coin.Collected += AddCoin;
}
void OnDisable()
{
Coin.Collected -= AddCoin;
}
void AddCoin(Coin coin)
{
score += coin.value;
}يظل الحدث الثابت موجودًا طوال مدة اللعبة، لذا فإن -= أهم من أي وقت مضى: فسيظل استدعاء ScoreBoard الذي دُمّر ولم يُلغِ اشتراكه ممكنًا، وسيفشل كوده عند التعامل مع النص الذي دُمّر. يأتي OnEnable وOnDisable في أزواج، لذا يقابل كل += عامل -=.
التحدي
سهليحتاج القاعدة إلى أرواح، ويجب أن يتسبب العدو الذي يصل إليها في خسارتها.
- في
EnemyData، أضفdamageمن النوع int واجعله عامًا: عدد الأرواح التي يخصمها هذا النوع من القاعدة. - في
Enemy، صرّح عن الحدث العام والثابتReachedBaseالذي يمرر العدو (Action<Enemy>). عندما يصل العدو إلى نقطة المسار الأخيرة، أطلق الحدث مع تمرير العدو نفسه ودمّر العدو، بدلًا من التوقف هناك. - في
GameManager، أضف int متسلسلًاstartLives(20) وint خاصًاlivesيبدأ بهذه القيمة. اشترك فيEnemy.ReachedBaseداخلOnEnableوألغِ الاشتراك داخلOnDisable. يخصم كل عدو يصل إلى القاعدة قيمةdamageالخاصة بأصله من الأرواح. - اعرض الأرواح في
livesTextمن نوع TMP_Text متسلسل، بالشكلLives: 20، عند البداية وبعد كل تغيير.
يحتوي كائن Game على GameManager، ويربط Inspector عنصر LivesText، ويخصم كلا الأصلين حياة واحدة. اضغط Play، وانتظر حتى يصل العدوان إلى القاعدة، ثم اضغط Check.
جرّب بنفسك
using UnityEngine;
public class Enemy : MonoBehaviour
{
public EnemyData data;
public Transform[] waypoints;
private int next = 1;
private int health;
void Awake()
{
health = data.maxHealth;
}
void Update()
{
if (next >= waypoints.Length)
{
return;
}
Vector3 target = waypoints[next].position;
transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
if (transform.position == target)
{
next++;
}
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.