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

آلة حالات

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

ستكون طريقة SetState الخاصة بالمنارة هي نفسها في كل كائن له حالات: برج، عدو، باب. يمكن أن يكون هذا الكود في صنف مستقل، وهو آلة حالات تحتفظ بالحالة الحالية وتغيّرها. ينشئ كل كائن آلة واحدة ويستدعيها بدلًا من تكرار الكود:

public class StateMachine
{
    public IState Current { get; private set; }

    public void ChangeState(IState next)
    {
        Current?.Exit();
        Current = next;
        Current.Enter();
    }

    public void Tick()
    {
        Current?.Tick();
    }
}

public class Beacon : MonoBehaviour
{
    public Renderer lamp;
    private StateMachine machine = new StateMachine();
    private IState blink;
    private IState steady;

    void Start()
    {
        blink = new BlinkState(lamp);
        steady = new SteadyState();
        machine.ChangeState(steady);
    }

    void Update()
    {
        if (Keyboard.current.spaceKey.wasPressedThisFrame) machine.ChangeState(machine.Current == steady ? blink : steady);
        machine.Tick();
    }
}

لا توجد حالة لمغادرتها عند استدعاء ChangeState لأول مرة: Current تساوي null، و?. يتخطى استدعاء Exit. حذّر القسم 1 من أن ?. لا يتعامل مع القيمة null الوهمية في Unity؛ وهذا يتعلق بكائنات Unity التي دُمّرت، أما الحالات فهي كائنات C# عادية، لذا فإن ?. آمن هنا. لدى Current أداة ضبط private set، لذا لا يستطيع أي نص برمجي تبديل الحالة من دون المرور عبر ChangeState واستدعاء Exit وEnter.

الترتيب داخل ChangeState مهم كلما أثّرت حالتان في الشيء نفسه. يتراجع Exit عن التغييرات التي أجرتها الحالة القديمة، ثم يهيّئ Enter الحالة الجديدة، فتكون الكلمة الأخيرة للحالة الجديدة. إذا أطفأ Enter في DarkState المصباح ونُفّذ قبل Exit في BlinkState، فسيعيد Exit تشغيل المصباح في الحالة المظلمة. آلة الحالات StateMachine صنف عادي أيضًا: تنشئ المنارة والبرج والعدو كلٌّ منها آلة خاصة بها باستخدام new، وتستدعي Tick الخاصة بها من Update.

challenge icon

التحدي

متوسط

اضغط باستمرار على Space للتسلل. أصبح WalkState وSneakState جاهزتين في PlayerStates.cs: تسجلان ما يحدث عند Enter وExit (Walk: enter، Sneak: exit...)، وتستدعي Tick فيهما Move() للاعب. اكتب الآلة التي تشغّلهما.

  • في StateMachine.cs، اكتب فئة عادية StateMachine مع خاصية عامة Current لا يمكن ضبطها إلا بواسطة الآلة، وطريقة ChangeState(IState next) تستدعي Exit للحالة القديمة، ثم Enter للحالة الجديدة، وطريقة Tick() تستدعي Tick للحالة الحالية.
  • يطلب اللاعب حالته في كل إطار، لذلك لا تفعل ChangeState شيئًا إذا كانت الحالة المطلوب الانتقال إليها هي الحالة الحالية بالفعل: لا Exit ولا Enter.
  • في Player.cs، أضف حقلًا من النوع StateMachine اسمه machine. في Start، أنشئ الآلة والحالتين (تأخذ كل منهما اللاعب) وابدأ بالمشي. في Update، انتقل إلى التسلل ما دام Space مضغوطًا، وإلى المشي خلاف ذلك، ثم نفّذ Tick للآلة.

اضغط تشغيل، وامشِ، واضغط باستمرار على Space وواصل المشي، ثم اضغط تحقّق.

جرّب بنفسك

// StateMachine: Current وChangeState وTick
quiz iconاختبر نفسك

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

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