الأحداث في C# ضمن Unity
جزء من قسم هندسة الألعاب في Unity في رحلة Unity على Coddy. الدرس 10 من 50.
عندما تتغير النتيجة، تهتم عدة أشياء بذلك: نص النتيجة، وصوت، وإنجاز. إذا استدعى ScoreKeeper كلًّا منها، فسيحتاج إلى حقل لكل واحد، وكل ميزة جديدة تعني تعديله. يقلب الحدث الأمر: يعلن ScoreKeeper عن التغيير، ويشترك كل من يهتم به. تعرف event وAction من C#. في Unity، يكون الناشر والمستمعون مكوّنات، عادةً على GameObjects مختلفة:
using System;
using UnityEngine;
public class ScoreKeeper : MonoBehaviour
{
public event Action<int> OnScoreChanged;
private int score;
public void AddPoints(int points)
{
score += points;
OnScoreChanged?.Invoke(score);
}
}// ScoreLabel.cs، على نص واجهة عرض المعلومات (HUD)
public ScoreKeeper keeper;
public TMP_Text label;
void Start()
{
keeper.OnScoreChanged += ShowScore;
}
void ShowScore(int score)
{
label.text = "Score: " + score;
}تعني Action<int> أن كل مستمع هو أسلوب يأخذ قيمة int واحدة، وهي هنا النتيجة الجديدة. تستدعي Invoke كل أسلوب مشترك، بالترتيب الذي اشتركوا به. إذا لم يكن هناك مستمع، يكون الحدث null، لذا فإن OnScoreChanged(score) العادي سيؤدي إلى NullReferenceException، بينما تتخطى ?. الاستدعاء بدلًا من ذلك. تحصر الكلمة المفتاحية event السكريبتات الأخرى في استخدام += و-=: في ScoreLabel، لن يُترجم keeper.OnScoreChanged(5) أو keeper.OnScoreChanged = null.
ليس لدى ScoreKeeper حقل للتسمية ولا يعرف بوجودها. يشترك عدّاد الكومبو أو مشغّل الصوت بالطريقة نفسها، ويبقى ScoreKeeper كما هو، كما يعمل مشهد اختبار بلا HUD دون أخطاء. يعثر المستمع على الناشر عبر مرجع Inspector، كما في المثال هنا، أو بأي طريقة تعرفها، مثل GetComponent أو singleton. إزالة مستمع باستخدام -= مهمة بعد تدمير الكائنات، وهذا موضوع الدرس التالي.
التحدي
سهليزداد عدد الضربات المتتالية للمقاتل مع كل ضغطة على Space، ويعود إلى 0 بعد مرور ثانية واحدة دون ضربة، أي بعد comboWindow (1). حاليًا، يضبط Fighter.cs نص الضربات المتتالية وحجم اللهب بنفسه، لذا يحتاج إلى حقل لكل منهما. غيّر ذلك باستخدام حدث:
- في
Fighter.cs، أعلن عن حدث عام باسمOnComboChangedيمرر عدد الضربات المتتالية (عددًا صحيحًا). أطلق الحدث مع العدد الجديد في كل مرة يتغير فيها عدد الضربات المتتالية، بما في ذلك إعادة الضبط إلى 0، وتأكد من أن الضربة لا تسبب خطأً عندما لا يستمع أي طرف. - احذف حقلي
comboTextوflameمن Fighter والأسطر التي تستخدمهما: لا يعرف Fighter شيئًا عن HUD. - في
ComboText.csوComboFlame.cs، اشترك في حدث المقاتل باستخدام الدالتينShowوGrowفيStart(). يحتوي كلاهما على حقلfighterمرتبط في المشهد.
اضغط على Play، واضرب الكيس باستخدام Space بضع مرات، وانتظر ثانية، ثم اضغط على Check.
جرّب بنفسك
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;
public class Fighter : MonoBehaviour
{
public float comboWindow = 1f;
public TMP_Text comboText;
public Transform flame;
private int combo;
private float sinceHit;
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
combo++;
sinceHit = 0f;
comboText.text = "Combo x" + combo;
flame.localScale = Vector3.one * (0.5f + 0.25f * combo);
}
else if (combo > 0)
{
sinceHit += Time.deltaTime;
if (sinceHit > comboWindow)
{
combo = 0;
comboText.text = "";
flame.localScale = Vector3.one * 0.5f;
}
}
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس هندسة الألعاب في Unity
1المكوّنات لا التسلسلات الهرمية
مكوّنات صغيرةسكربت أساسي للعدومكوّنات مجرّدةتعمل المكوّنات معًامراجعة: برج دفاعي معياري4البيانات المتسلسلة
الأصناف القابلة للتسلسلالقوائم في Inspectorالتعدادات في Inspectorمراجعة: جدول الغنائم10مشروع: الناجي في الساحة
البطلأنواع الأعداء3الأحداث
الأحداث في C# ضمن Unityالاشتراك في OnEnableحقول UnityEventالأحداث تحرّك واجهة المستخدممراجعة: نافذة الإنجاز المنبثقة