Menu
CoddyTech
flag Ar iconالعربيةdown icon

الأحداث في 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. إزالة مستمع باستخدام -= مهمة بعد تدمير الكائنات، وهذا موضوع الدرس التالي.

challenge icon

التحدي

سهل

يزداد عدد الضربات المتتالية للمقاتل مع كل ضغطة على 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;
            }
        }
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

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