آلة حالات
جزء من قسم هندسة الألعاب في 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.
التحدي
متوسطاضغط باستمرار على 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
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس هندسة الألعاب في Unity
1المكوّنات لا التسلسلات الهرمية
مكوّنات صغيرةسكربت أساسي للعدومكوّنات مجرّدةتعمل المكوّنات معًامراجعة: برج دفاعي معياري4البيانات المتسلسلة
الأصناف القابلة للتسلسلالقوائم في Inspectorالتعدادات في Inspectorمراجعة: جدول الغنائم10مشروع: الناجي في الساحة
البطلأنواع الأعداء