استخدام الذكاء الاصطناعي في Unreal Engine 4

في ألعاب الفيديو، يشير الذكاء الاصطناعي (AI) عادةً إلى كيفية اتخاذ شخصية غير اللاعب للقرارات، وقد يكون هذا بسيطاً مثل رؤية عدو للاعب ثم مهاجمته، ويمكن أن يكون أيضاً شيئاً أكثر تعقيداً مثل لاعب يتحكم فيه الذكاء الاصطناعي في استراتيجية الوقت الفعلي.

في أنريل إينجن (Unreal Engine)، يمكنك إنشاء ذكاء اصطناعي باستخدام ما يسمى أشجار السلوك (behavior trees).

وشجرة السلوك هي نظام يستخدم لتحديد السلوك الذي يجب أن يؤديه الذكاء الاصطناعي، على سبيل المثال، يمكن أن يكون لديك سلوك قتال وجري، فيمكنك إنشاء شجرة السلوك بحيث يقاتل الذكاء الاصطناعي إذا كان مستوى الصحة أعلى من 50 بالمئة، وإذا كانت أقل من 50 بالمئة، فسوف تهرب.

ستتعلم في هذا البرنامج التعليمي كيفية:

  1. إنشاء كيان ذكاء اصطناعي (AI) يمكنه التحكم في اللاعب.
  2. إنشاء واستخدام أشجار السلوك والسبورات.
  3. استخدم تصور الذكاء الاصطناعي لصناعة المشاهد.
  4. ابتكار سلوكيات تجعل اللاعب يتجول ويهاجم الأعداء.

البداية

قم بتنزيل مشروع البداية وفك ضغطه، ثم انتقل إلى مجلد المشروع (project folder) وافتح (MuffinWar.uproject).

اضغط على تشغيل (Play) لبدء اللعبة، وانقر بزر الماوس الأيسر داخل المنطقة المسيجة لتولد الكعك.

الشكل البدائي للعبة

في هذا البرنامج التعليمي، ستقوم بإنشاء ذكاء اصطناعي (AI) يتجول فيه، وعندما تدخل فطيرة العدو في نطاق رؤية الذكاء الاصطناعي، سينتقل الذكاء الاصطناعي إلى العدو ويهاجمه.

لإنشاء شخصية ذكاء اصطناعي (AI)، تحتاج إلى ثلاثة أشياء:

  1. الجسم (Body): وهو التمثيل المادي للشخصية، وفي هذه الحالة، الكعك هو الجسد.
  2. الروح (Soul): الروح هي الكيان الذي يتحكم بالشخصية، وقد يكون هذا هو اللاعب أو الذكاء الاصطناعي (AI).
  3. الدماغ (Brain): الدماغ هو الطريقة التي يتخذ بها الذكاء الاصطناعي القرارات، ويمكنك إنشاء هذا بطرق مختلفة مثل كود C ++ أو المخططات (Blueprints) أو أشجار السلوك (behavior trees).

نظراً لأنك تمتلك الجسد بالفعل، فكل ما تحتاجه هو روح وعقل، أولاً، ستنشئ متحكم (controller) سيكون هو الروح.

ما هو المتحكم (controller)؟

المتحكم هو ممثل غير مادي يمكنه امتلاك اللاعب، ويسمح الامتلاك للمتحكم بالتحكم باللاعب، ولكن ماذا تعني كلمة “التحكم” في هذا السياق؟

بالنسبة للمستخدم، هذا يعني الضغط على زر وجعل اللاعب يفعل شيئاً ما، يستقبل المتحكم المدخلات من المستخدم وبعد ذلك يمكن إرسال المدخلات إلى اللاعب، ويمكن للمتحكم أيضاً التعامل مع المدخلات بدلاً من ذلك ثم إخبار اللاعب بتنفيذ إجراء معين.

المتحكم

في حالة الذكاء الاصطناعي (AI)، يمكن أن يتلقى اللاعب معلومات من المتحكم أو الدماغ (اعتماداً على كيفية برمجته).

وللتحكم في الكعك باستخدام الذكاء الاصطناعي (AI)، تحتاج إلى إنشاء نوع خاص من المتحكم يعرف باسم متحكم الذكاء الاصطناعي (AI controller).

إنشاء متحكم الذكاء الاصطناعي (AI controller)

انتقل إلى (Characters \ Muffin \ AI) وأنشئ فئة مخطط (Blueprint) جديدة، وحدد (AIController) كفئة رئيسية وقم بتسميتها (AIC_Muffin).

إنشاء متحكم الذكاء الاصطناعي

بعد ذلك، عليك إخبار الكعك باستخدام متحكم الذكاء الاصطناعي (AI controller) الجديد، ثم انتقل إلى (Characters \ Muffin \ Blueprints) وافتح (BP_Muffin).

بشكل افتراضي، يجب أن تعرض لوحة التفاصيل (Details panel) الإعدادات الافتراضية للمخطط (Blueprint)، وإذا لم يحدث ذلك، فانقر على الإعدادات الافتراضية للفئة (Class Defaults) في شريط الأدوات (Toolbar).

شريط الأدوات

انتقل إلى لوحة التفاصيل (Details panel) وحدد موقع قسم اللاعب (Pawn section)، وقم بضبط متحكم الذكاء الاصطناعي (AI controller) على (AIC_Muffin)، وسيؤدي هذا إلى ظهور مثيل للمتحكم عندما تولد الكعك.

إعداد الكعك

نظراً لأنك تقوم بتوليد الكعك، فأنت بحاجة أيضاً إلى ضبط (Auto Possess AI) على (Spawned)، وسيؤدي هذا إلى التأكد من أن (AIC_Muffin) يمتلك تلقائياً (BP_Muffin) عند إنتاجه.

ضبط توليد الكع بالذكاء الصنعي

انقر فوق (Compile) ثم أغلق (BP_Muffin).

الآن، ستنشئ المنطق الذي سيقود سلوك الكعك، وللقيام بذلك، يمكنك استخدام أشجار السلوك (behavior trees).

إنشاء شجرة سلوك (Behavior Tree)

انتقل إلى (Characters \ Muffin \ AI) وحدد (Add New \ Artificial Intelligence \ Behavior Tree)، وسمها (BT_Muffin) ثم افتحه.

محرر شجرة السلوك (The Behavior Tree Editor)

يحتوي محرر شجرة السلوك على لوحتين جديدتين:

محرر شجرة السلوك

  1. شجرة السلوك (Behavior Tree): هذا الرسم البياني هو المكان الذي ستنشئ فيه عقد لإنشاء شجرة السلوك.
  2. التفاصيل (Details): ستعرض العقد التي تحددها خصائصها هنا.
  3. لوحة سوداء (Blackboard): ستعرض هذه اللوحة مفاتيح Blackboard (المزيد حول هذا لاحقاً) وقيمها، وسيتم عرضها فقط عندما تكون اللعبة قيد التشغيل.

مثل المخططات (Blueprints)، تتكون أشجار السلوك (behavior trees) من عقد، وهناك أربعة أنواع من العقد في أشجار السلوك، أول اثنتين منها هما المهام (tasks) والتراكيب (composites).

ما هي المهام (tasks) والتراكيب (composites)؟

كما يوحي اسمها، المهمة (task) هي عقدة تقوم بشيء ما، ويمكن أن يكون هذا شيء معقد مثل أداء التحرير والسرد، ويمكن أن يكون أيضاً شيء بسيط مثل الانتظار.

المهام والتراكيب

لتنفيذ المهام، تحتاج إلى استخدام التراكيب، وتتكون شجرة السلوك من العديد من الفروع (السلوكيات)، وفي جذر كل فرع هناك تركيب (composite)، والأنواع المختلفة من التراكيب (composites) لها طرق مختلفة لتنفيذ العقد الفرعية الخاصة بهم.

على سبيل المثال، لديك تسلسل الإجراءات التالي:

تسلسل

لتنفيذ كل إجراء في التسلسل، يمكنك استخدام تركيب تسلسل (Sequence composite)، وهذا لأن التسلسل ينفذ عناصره الفرعية من اليسار إلى اليمين، إليك ما سيبدو عليه الأمر:

تركيب تسلسل

ملاحظة: كل شيء يبدأ من تركيب (composite) يمكن أن يسمى شجرة فرعية (subtree)، وبشكل عام، هذه هي سلوكياتك، وفي هذا المثال، يمكن اعتبار التسلسل (Sequence) والتحرك إلى العدو (Move To Enemy) والدوران نحو العدو (Rotate Towards Enemy) والهجوم (Attack) سلوك هجوم العدو (attack enemy).

إذا فشل أي من العناصر الفرعية في التسلسل، فسيتوقف التسلسل عن التنفيذ.

على سبيل المثال، إذا كان اللاعب غير قادر على التحرك إلى العدو، فإن الحركة إلى العدو ستفشل، وهذا يعني أن برنامج الدوران نحو العدو لن يتم تنفيذه ولن يتم تنفيذ الهجوم، ومع ذلك، سوف يتم التنفيذ إذا نجح اللاعب في الانتقال إلى العدو.

لاحقاً، ستتعرف أيضاً على تركيب المحدد (Selector composite)، وفي الوقت الحالي، ستستخدم التسلسل لتحريك اللاعب إلى موقع عشوائي ثم الانتظار.

الانتقال إلى موقع عشوائي

قم بإنشاء تسلسل (Sequence) وقم بتوصيله بالجذر (Root).

الانتقال إلى موقع عشوائي

بعد ذلك، تحتاج إلى تحريك اللاعب، قم بإنشاء (MoveTo) وتوصيله بالتسلسل (Sequence)، وستنقل هذه العقدة اللاعب إلى موقع أو ممثل محدد.

تحريك اللاعب

بعد ذلك، قم بإنشاء انتظار (Wait) وقم بتوصيله بالتسلسل، وتأكد من وضعه على يمين (MoveTo)، الترتيب مهم هنا لأن التنفيذ سوف يتم من اليسار إلى اليمين.

انتظار

ملاحظة: يمكنك التحقق من ترتيب التنفيذ من خلال النظر إلى الأرقام في أعلى يمين كل عقدة، والعقد ذات الأرقام الأقل لها الأولوية على العقد ذات الأرقام الأعلى.

لقد قمت بإنشاء سلوكك الأول، وسوف ينقل اللاعب إلى مكان محدد ثم ينتظر لمدة خمس ثوان.

لتحريك اللاعب، تحتاج إلى تحديد مكان، ومع ذلك، لا يقبل (MoveTo) سوى القيم المقدمة من خلال اللوحات السوداء (blackboards)، لذا ستحتاج إلى إنشاء واحدة.

إنشاء لوحة سوداء (Blackboard)

اللوحة السوداء (Blackboard) هي أصل وظيفته الوحيدة هي الاحتفاظ بالمتغيرات (المعروفة باسم المفاتيح keys)، ويمكنك التفكير في الأمر على أنه ذاكرة الذكاء الاصطناعي.

على الرغم من أنك لست مطالباً باستخدامها، فإن اللوحات السوداء (blackboards) توفر طريقة ملائمة لقراءة البيانات وتخزينها، وهي ملائمة لأن العديد من العقد في أشجار السلوك تقبل مفاتيح اللوحة السوداء فقط.

لإنشاء لوحة سوداء (Blackboard)، ارجع إلى مستعرض المحتوى (Content Browser) وحدد (Add New\Artificial Intelligence\Blackboard)، وسمها (BB_Muffin) ثم افتحه.

محرر اللوحة السوداء (The Blackboard Editor)

يتكون محرر اللوحة السوداء من لوحتين:

محرر اللوحة السوداء

  1. لوحة سوداء (Blackboard): ستعرض هذه اللوحة قائمة بالمفاتيح (keys) الخاصة بك.
  2. تفاصيل اللوحة السوداء (Blackboard Details): ستعرض هذه اللوحة خصائص المفتاح المحدد.

الآن، تحتاج إلى إنشاء مفتاح (key) يحمل الموقع المستهدف.

إنشاء مفتاح الموقع المستهدف

نظراً لأنك تقوم بتخزين موقع في مساحة ثلاثية الأبعاد، فأنت بحاجة إلى تخزينه كشعاع، انقر فوق مفتاح جديد (New Key) وحدد شعاع (Vector)، وسمه (TargetLocation).

إنشاء مفتاح الموقع المستهدف

بعد ذلك، تحتاج إلى طريقة لإنشاء موقع عشوائي وتخزينه في اللوحة السوداء (Blackboard)، وللقيام بذلك، يمكنك استخدام النوع الثالث من عقدة شجرة السلوك وهي الخدمة (service).

ما هي الخدمة (Service)؟

الخدمات (Services) مثل المهام (tasks) التي تستخدمها لفعل شيء ما، ومع ذلك، بدلاً من جعل اللاعب ينفذ إجراءً ما، فإنك تستخدم الخدمات (Services) لإجراء عمليات التحقق أو تحديث اللوحة السوداء.

الخدمات (Services) ليست عقد فردية، وبدلاً من ذلك، يتم إرفاقهم بالمهام (tasks) أو التراكيب (composites)، وينتج عن هذا شجرة سلوك (behavior tree) أكثر تنظيماً لأن لديك عقد أقل للتعامل معها، وإليك كيف ستبدو باستخدام مهمة (task):

استخدام مهمة

إليك كيف ستبدو عند استخدام خدمة (service):

استخدام خدمة

حان الوقت الآن لإنشاء خدمة (service) تُنشئ موقع عشوائي.

إنشاء خدمة (Service)

ارجع إلى (BT_Muffin) وانقر على خدمة جديدة (New Service).

إنشاء خدمة

سيؤدي هذا إلى إنشاء خدمة جديدة وفتحها تلقائياً، سمها (BTService_SetRandomLocation)، ستحتاج إلى الرجوع إلى متصفح المحتوى (Content Browser) لإعادة تسميتها.

الخدمة تحتاج فقط إلى التنفيذ عندما يريد اللاعب التحرك، وللقيام بذلك، تحتاج إلى إرفاقه بـ (MoveTo).

افتح (BT_Muffin) ثم انقر بزر الماوس الأيمن على (MoveTo)، وحدد (Add Service \ BTService Set Random Location).

إضافة التحرك إلى

الآن، سيتم تنشيط (BTService_SetRandomLocation) عند تنشيط (MoveTo).

بعد ذلك، تحتاج إلى إنشاء موقع هدف عشوائي.

إنشاء موقع عشوائي

افتح (BTService_SetRandomLocation).

لمعرفة وقت تنشيط الخدمة، قم بإنشاء عقدة ذكاء اصطناعي لتفعيل تلقي الحدث (Event Receive Activation AI)، وسيتم تنفيذ هذا عندما يتم تنشيط مولد الخدمة (العقدة المرتبطة بها).

إنشاء موقع عشوائي

ملاحظة: هناك أيضاً حدث آخر يسمى تنشيط تلقي الأحداث (Event Receive Activation) والذي يقوم بنفس الشيء، والفرق بين الحدثين هو أن (Event Receive Activation AI) يدعم أيضاً اللاعب المتحكم فيه.

لإنشاء موقع عشوائي، أضف العقد المميزة (highlighted)، تأكد من ضبط نصف القطر (Radius) على 500.

ضبط نصف القطر

سيعطيك هذا موقع قابل للتنقل بشكل عشوائي ضمن 500 وحدة من اللاعب.

ملاحظة: يستخدم (GetRandomPointInNavigableRadius) بيانات التنقل (تسمى NavMesh) لتحديد ما إذا كانت نقطة ما قابلة للتنقل أم لا، وفي هذا البرنامج التعليمي، قمت بالفعل بإنشاء شبكة تنقل (NavMesh) من أجلك، ويمكنك رؤية ذلك بالانتقال إلى منفذ العرض (Viewport) وتحديد (Show\Navigation).

موقع قابل للتنقل

إذا كنت ترغب في إنشاء (NavMesh) الخاص بك، فقم بإنشاء (Nav Mesh Bounds Volume)، وقم بقياس حجمها بحيث تغطي المنطقة التي تريد أن تكون قابلة للتنقل فيها.

بعد ذلك، تحتاج إلى تخزين الموقع في اللوحة السوداء (blackboard)، وهناك طريقتان لتحديد أي مفتاح (key) يجب استخدامه:

  1. يمكنك تحديد المفتاح باستخدام اسمه في عقدة (Make Literal Name).
  2. يمكنك عرض متغير لشجرة السلوك، وسيسمح لك ذلك بتحديد مفتاح من القائمة المنسدلة.

ستستخدم الطريقة الثانية، قم بإنشاء متغير من نوع (Blackboard Key Selector)، وقم بتسميته (BlackboardKey) وقم بتمكين (Instance Editable)، حيث سيسمح هذا للمتغير بالظهور عند تحديد الخدمة في شجرة السلوك.

تخزين الموقع في اللوحة السوداء

بعد ذلك، قم بإنشاء العقد المميزة:

إنشاء العقد المميزة

ملخص:

  1. يتم تنفيذ (Event Receive Activation AI) عندما يتم تنشيطه من قِبل أحد المولّدين (في هذه الحالة، MoveTo).
  2. يُرجع (GetRandomPointInNavigableRadius) موقعاً عشوائياً قابلاً للتنقل ضمن 500 وحدة من الكعك الخاضع للرقابة.
  3. تعيين قيمة (Blackboard) كشعاع (Vector) يعين قيمة مفتاح اللوحة (الذي يوفره BlackboardKey) على الموقع العشوائي.

انقر فوق (Compile) ثم أغلق (BTService_SetRandomLocation).

بعد ذلك، عليك إخبار شجرة السلوك (behavior tree) باستخدام اللوحة (blackboard).

تحديد اللوحة السوداء (Blackboard)

افتح (BT_Muffin) وتأكد من عدم تحديد أي شيء، وانتقل إلى لوحة التفاصيل (Details panel)، ضمن شجرة السلوك (behavior tree)، قم بضبط أصل (Blackboard) على (BB_Muffin).

تحديد اللوحة السوداء

بعد ذلك، ستستخدم (MoveTo) و (BTService_SetRandomLocation) أول مفتاح للوحة تلقائياً، وفي هذه الحالة، يكون الهدف هو (TargetLocation).

استخدام التحرك إلى

أخيراً، تحتاج إلى إخبار المتحكم في الذكاء الاصطناعي (AI controller) بتشغيل شجرة السلوك (behavior tree).

تشغيل شجرة السلوك (Behavior Tree)

افتح (AIC_Muffin) وقم بتوصيل (Run Behavior Tree) بحدث (BeginPlay)، واضبط (BTAsset) على (BT_Muffin).

تشغيل شجرة السلوك

سيؤدي هذا إلى تشغيل (BT_Muffin) عندما يولد (AIC_Controller).

انقر فوق (Compile) ثم ارجع إلى المحرر الرئيسي، اضغط على تشغيل (Play)، وضع بعض الكعك وشاهدها وهي تتجول.

تجول الكعك في اللعبة

بعد ذلك، ستقوم بإعداد متحكم الذكاء الاصطناعي (AI controller) بحيث يمكنه اكتشاف الأعداء في نطاق رؤيته، وللقيام بذلك، يمكنك استخدام (AI Perception).

ضبط رؤية الذكاء الاصطناعي (AI Perception)

يعتبر (AI Perception) مكون يمكنك إضافته إلى اللاعبين، وباستخدامه يمكنك إعطاء الحواس (مثل البصر والسمع) للذكاء الاصطناعي (AI) الخاص بك.

افتح (AIC_Muffin) ثم قم بإضافة مكون (AIPerception).

ضبط رؤية الذكاء الاصطناعي

بعد ذلك، تحتاج إلى إضافة حاسة، نظراً لأنك تريد اكتشاف متى تتحرك فطيرة أخرى في العرض، فأنت بحاجة إلى إضافة حاسة البصر (sight sense).

حدد (AIPerception) ثم انتقل إلى لوحة التفاصيل (Details panel)، ضمن (AI Perception)، أضف عنصر جديد إلى (Senses Config).

إضافة حاسة 1

اضبط العنصر 0 على تكوين (AI Sight) ثم قم بتوسيعه.

حاسة 2

هناك ثلاثة إعدادات رئيسية للرؤية:

  1. نصف قطر البصر (Sight Radius): أقصى مسافة يمكن أن يراها الكعك، اترك هذا عند 3000.
  2. فقدان البصر (Lose Sight Radius): إذا رأى الكعك عدواً، فهذه هي المسافة التي يجب أن يتحرك بها العدو بعيداً قبل أن يغيب عن الكعك رؤيته، اترك هذا عند 3500.
  3. درجات نصف زاوية الرؤية المحيطية (Peripheral Vision Half Angle Degrees): مدى اتساع رؤية الكعك، اضبط هذا على 45، سيعطي هذا الكعك نطاق رؤية 90 درجة.

إعدادات الرؤية

بشكل افتراضي، يكتشف (AI Perception) الأعداء فقط (اللاعبين المعينين لفريق مختلف)، ومع ذلك، لا يمتلك اللاعبون فريق بشكل افتراضي، وعندما لا يكون للاعب فريق، فإن (AI Perception) يعتبره محايداً.

ولا توجد طريقة لتعيين فرق باستخدام المخططات (Blueprints)، وبدلاً من ذلك، يمكنك فقط يمكن إخبار (AI Perpcetion) لاكتشاف الجهات الفاعلة المحايدة، وللقيام بذلك، قم بتوسيع الكشف عن طريق الانتساب (Detection by Affiliation) وتمكين الكشف عن الحياد (Detect Neutrals).

إعداد اكتشاف الأعداء

انقر فوق (Compile) ثم ارجع إلى المحرر الرئيسي، واضغط على تشغيل (Play) وضع بعض الكعك، ثم اضغط على (key to display the AI debug screen)، واضغط 4 على اللوحة الرقمية لضبط رؤية الذكاء الاصطناعي، وعندما يتحرك الكعك في العرض، ستظهر كرة خضراء.

الكعك يتحرك بالعرض

بعد ذلك، سوف تحرّك الكعك نحو العدو، وللقيام بذلك، يجب أن تعرّف شجرة السلوك على العدو، ويمكنك القيام بذلك عن طريق تخزين مرجع للعدو في اللوحة السوداء.

إنشاء مفتاح العدو (Enemy Key)

افتح (BB_Muffin) ثم قم بإضافة مفتاح من النوع (Object)، أعد تسميته إلى (Enemy).

إنشاء مفتاح العدو (Enemy Key)

في الوقت الحالي، لن تتمكن من استخدام (Enemy) في (MoveTo)، وهذا لأن المفتاح هو كائن ولكن (MoveTo) يقبل فقط مفاتيح من النوع (Vector) أو (Actor).

لإصلاح ذلك، حدد (Enemy) ثم قم بتوسيع نوع المفتاح (Key Type)، واضبط الفئة الأساسية (Base Class) على الممثل (Actor)، وسيسمح هذا لشجرة السلوك بالتعرف على العدو كممثل.

إعدادات مفتاح العدو

أغلق (BB_Muffin)، والآن، تحتاج إلى إنشاء سلوك للتحرك نحو العدو.

التحرك نحو العدو

افتح (BT_Muffin) ثم افصل التسلسل (Sequence) والجذر (Root)، يمكنك القيام بذلك عن طريق النقر فوق السلك الذي يربط بينهما، وضع الشجرة الفرعية (subtree) جانباً في الوقت الحالي.

بعد ذلك، قم بإنشاء العقد المميزة (highlighted) واضبط (Blackboard Key) على (Enemy):

التحرك نحو العدو

هذا سوف يحرك اللاعب تجاه العدو، وفي بعض الحالات، لن يتجه اللاعب تماماً نحو هدفه، لذا يمكنك أيضاً استخدام (Rotate to face BB entry).

ضبط مفتاح العدو (Enemy Key)

افتح (AIC_Muffin) ثم حدد مكون (AIPerception)، وأضف حدث (On Perception Updated).

ضبط مفتاح العدو (Enemy Key)

سيتم تنفيذ هذا الحدث كلما تم تحديث الإحساس، وفي هذه الحالة، عندما يرى الذكاء الاصطناعي (AI) شيء أو يغفل عنه، ويوفر هذا الحدث أيضاً قائمة بالجهات الفاعلة التي يتحسسها حالياً.

أضف العقد المميزة (highlighted)، تأكد من ضبط (Make Literal Name to Enemy).

التأكد من ضبط العدو

سيؤدي هذا إلى التحقق مما إذا كان للذكاء الاصطناعي عدو بالفعل، وإذا لم يكن الأمر كذلك، فأنت بحاجة إلى إعطائه واحد، وللقيام بذلك، أضف العقد المميزة (highlighted):

إضافة عقد مميزة

ملخص:

  1. سيتحقق (IsValid) من ضبط (Enemy key).
  2. إذا لم يتم تعيينه، فقم بالتكرار على جميع الممثلين المحسوسين حالياً.
  3. سوف يقوم (Cast To BP_Muffin) بالتحقق مما إذا كان الممثل عبارة عن فطيرة.
  4. إذا كانت فطيرة، تحقق مما إذا كانت ميتة.
  5. إذا أعاد (IsDead) خطأ، فقم بتعيين الكعك على أنه العدو الجديد ثم كسر الحلقة.

انقر فوق (Compile) ثم أغلق (AIC_Muffin)، واضغط على تشغيل (Play) ثم قم بتوليد اثنين من الكعك بحيث يكون أحدهما أمام الآخر، والكعك الموجود في الخلف سوف يسير تلقائياً نحو الكعك الآخر.

التحرك نحوالعدو

بعد ذلك، ستقوم بإنشاء مهمة مخصصة (custom task) لجعل الكعك يقوم بهجوم.

إنشاء مهمة هجوم (Attack Task)

يمكنك إنشاء مهمة (task) داخل مستعرض المحتوى (Content Browser) بدلاً من محرر شجرة السلوك (behavior tree editor)، قم بإنشاء فئة مخطط (Blueprint Class) جديدة وحدد (BTTask_BlueprintBase) كأصل.

إنشاء مهمة هجوم (Attack Task)

قم بتسميته (BTTask_Attack) ثم افتحه، أضف عقدة (Event Receive Execute AI)، وسيتم تنفيذ هذه العقدة عند تنفيذ شجرة السلوك (BTTask_Attack).

مهمة الهجوم

أولاً، تحتاج إلى القيام بهجوم الكعك، يحتوي (BP_Muffin) على متغير (IsAttacking)، وعند تحققه، ستنفذ الكعك هجوماً، وللقيام بذلك، أضف العقد المميزة (highlighted):

العقد المميزة في مهمة الهجوم

إذا كنت تستخدم المهمة (task) في حالتها الحالية، فسيتعطل التنفيذ فيها، وهذا لأن شجرة السلوك لا تعرف ما إذا كانت المهمة قد انتهت، ولإصلاح ذلك، أضف إنهاء التنفيذ (Finish Execute) إلى نهاية السلسلة.

إنهاء التنفيذ

بعد ذلك، قم بتمكين النجاح (Success)، نظراً لأنك تستخدم تسلسل، فسيتيح ذلك تنفيذ العقد بعد (BTTask_Attack).

تمكين النجاح

هذا ما يجب أن يبدو عليه الرسم البياني الخاص بك:

الرسم البياني

ملخص:

  1. سيتم تنفيذ (Event Receive Execute AI) عند تشغيل شجرة السلوك (BTTask_Attack).
  2. سيتحقق (Cast To BP_Muffin) مما إذا كان البيدق المُتحكم به من نوع (BP_Muffin).
  3. إذا كان الأمر كذلك، يتم تعيين متغير (IsAttacking) الخاص به.
  4. سيسمح إنهاء التنفيذ (Finish Execute) لشجرة السلوك بمعرفة أن المهمة قد انتهت بنجاح.

انقر فوق (Compile) ثم قم بإغلاق (BTTask_Attack).

الآن، تحتاج إلى إضافة (BTTask_Attack) إلى شجرة السلوك.

إضافة الهجوم إلى شجرة السلوك (Adding Attack to the Behavior Tree)

افتح (BT_Muffin)، وبعد ذلك، أضف (BTTask_Attack) إلى نهاية التسلسل (Sequence).

إضافة الهجوم إلى شجرة السلوك

بعد ذلك، أضف انتظار (Wait) إلى نهاية التسلسل (Sequence)، اضبط وقت الانتظار (Wait Time) على 2، هذا سيضمن أن الكعك لا يهاجم باستمرار.

أضف انتظار (Wait) إلى نهاية التسلسل

ارجع إلى المحرر الرئيسي واضغط على تشغيل (Play)، قم بتوليد اثنين من الكعك مثل آخر مرة، وستتحرك الكعكة وتدور باتجاه العدو، وبعد ذلك، سوف تهاجم وتنتظر ثانيتين، وسيقوم بعد ذلك بتنفيذ التسلسل بأكمله مرة أخرى إذا رأى عدواً آخر.

الانتظار بعد مهاجمة العدو

في القسم الأخير، ستجمع بين الأشجار الفرعية للهجوم والتجول معاً.

الجمع بين الأشجار الفرعية (Subtrees)

لدمج الأشجار الفرعية، يمكنك استخدام تركيب محدد (Selector composite)، مثل التسلسلات (Sequences)، يتم تنفيذها أيضاً من اليسار إلى اليمين، ومع ذلك، سيتوقف المحدد (Selector) عندما النجاح، باستخدام هذا السلوك، يمكنك التأكد من أن شجرة السلوك تقوم بتنفيذ شجرة فرعية واحدة فقط.

افتح (BT_Muffin) ثم قم بإنشاء محدد (Selector) بعد عقدة الجذر (Root)، بعد ذلك، قم بتوصيل الأشجار الفرعية (subtrees) على النحو التالي:

الجمع بين الأشجار الفرعية

 

سيسمح هذا الإعداد بتشغيل شجرة فرعية واحدة فقط في كل مرة، وإليك كيفية تشغيل كل شجرة فرعية:

  • الهجوم (Attack): سيقوم المحدد (Selector) بتشغيل الشجرة الفرعية للهجوم (attack subtree) أولاً، وإذا نجحت جميع المهام (tasks)، سينجح التسلسل (Sequence) أيضاً، سيكتشف المحدد (Selector) هذا ثم يتوقف عن التنفيذ، وسيؤدي هذا إلى منع تشغيل الشجرة الفرعية المتجولة (roam subtree).
  • التجوال (Roam): سيحاول المحدد (Selector) تشغيل الشجرة الفرعية للهجوم (attack subtree) أولاً، وإذا لم يتم تعيين العدو، سيفشل (MoveTo)، وسيؤدي هذا إلى فشل التسلسل (Sequence) أيضاً، ومنذ فشل الشجرة الفرعية للهجوم، سيقوم المحدد بتنفيذ الفرع التالي وهو الشجرة الفرعية المتجولة (roam subtree).

ارجع إلى المحرر الرئيسي، واضغط تشغيل (Play) وقم بنشر بعض الكعك لاختبارها.

اختبار الجمع بين الأشجار الفرعية

لماذا لا تهاجم الكعكة الأخرى على الفور؟

في أشجار السلوك التقليدية، يبدأ التنفيذ من الجذر مع كل تحديث، هذا يعني أنه في كل تحديث، ستحاول شجرة الهجوم الفرعية العمل أولاً ثم الشجرة الفرعية المتجولة، وهذا يعني أن شجرة السلوك يمكنها على الفور تغيير الأشجار الفرعية إذا تغيرت قيمة العدو.

ومع ذلك، فإن أشجار سلوك أنريل (Unreal) لا تعمل بنفس الطريقة، في أنريل (Unreal)، ينتقل التنفيذ من آخر عقدة تم تنفيذها، ونظراً لأن (AI Perception) لا يستشعر الجهات الفاعلة الأخرى على الفور، تبدأ الشجرة الفرعية المتجولة في العمل، ويتعين على شجرة السلوك الآن انتظار انتهاء الشجرة الفرعية للتجوال قبل أن تتمكن من إعادة تمكين شجرة الهجوم الفرعية.

لإصلاح ذلك، يمكنك استخدام النوع الأخير من العقدة وهو المصمم (decorators).

إنشاء المصمم (Decorator)

مثل الخدمات (services)، يرتبط المصممون (decorators) بالمهام (tasks) أو التراكيب (composites)، وبشكل عام، يتم استخدام المصممون (decorators) لإجراء الفحوصات، وإذا كانت النتيجة صحيحة، فسيعود المصمم (decorator) أيضاً صحيح والعكس صحيح، وباستخدام هذا، يمكنك التحكم فيما إذا كان يمكن لأصل المصمم التنفيذ.

يمتلك المصممون أيضاً القدرة على إحباط الشجرة الفرعية، وهذا يعني أنه يمكنك إيقاف الشجرة الفرعية للتجول بمجرد تعيين العدو، وسيسمح هذا للفطيرة بمهاجمة العدو بمجرد اكتشافه.

لاستخدام الإحباط، يمكنك استخدام (Blackboard decorator)، يتحقق هذا ببساطة مما إذا كان مفتاح اللوحة (blackboard key) مضبوطاً أم لا.

افتح (BT_Muffin) ثم انقر بزر الماوس الأيمن فوق تسلسل الشجرة الفرعية للهجوم (Sequence of the attack subtree)، حدد (Add Decorator \ Blackboard)، وسيؤدي هذا إلى إرفاق (Blackboard decorator) بالتسلسل.

إنشاء المصمم

بعد ذلك، حدد (Blackboard decorator) وانتقل إلى لوحة التفاصيل (Details panel)، وقم بضبط (Blackboard Key) على (Enemy).

ضبط (Blackboard Key)

وسوف يتحقق هذا مما إذا كان العدو قد تم ضبطه، وإذا لم يتم التعيين، فسيفشل المصمم (decorator) ويتسبب في فشل التسلسل (sequence)، سيسمح هذا بعد ذلك للشجرة الفرعية بالعمل للتجوال.

من أجل إحباط الشجرة الفرعية للتجوال، تحتاج إلى استخدام إعداد إحباط المراقب (Observer Aborts).

استخدام إحباط المراقب (Observer Aborts)

سيؤدي إحباط المراقب (Observer Aborts) إلى إحباط شجرة فرعية (subtree) إذا تم تغيير مفتاح اللوحة (blackboard key) المحدد، هناك نوعان من الإحباط:

  1. ذاتي (Self): سيسمح هذا الإعداد للشجرة الفرعية للهجوم بإحباط نفسها عندما يصبح العدو غير صالح، ويمكن أن يحدث هذا إذا مات العدو قبل اكتمال الشجرة الفرعية للهجوم.
  2. أولوية أقل (Lower Priority): سيؤدي هذا الإعداد إلى إحباط الأشجار ذات الأولوية المنخفضة عند تعيين العدو، ونظراً لأن الشجرة الفرعية المتجولة تقع بعد الهجوم، فهي ذات أولوية أقل.

قم بضبط إحباط المراقب (Observer Aborts) على كليهما، وسيؤدي هذا إلى تمكين كلا النوعين من الإحباط.

استخدام إحباط المراقب (Observer Aborts)

الآن، يمكن لشجرة الهجوم الفرعية أن تتجول على الفور إذا لم يعد لديها عدو، وأيضاً، يمكن للشجرة الفرعية المتجولة الانتقال فوراً إلى وضع الهجوم بمجرد اكتشافها للعدو.

وها هي شجرة السلوك الكاملة:

شجرة السلوك الكاملة

ملخص الشجرة الفرعية للهجوم (attack subtree):

  1. سيقوم المحدد (Selector) بتشغيل الشجرة الفرعية للهجوم (attack subtree) إذا تم تعيين العدو (Enemy).
  2. إذا تم ضبطه، ستتحرك الكعكة ويدور باتجاه العدو.
  3. بعد ذلك، ستقوم بهجوم.
  4. أخيراً، ستنتظر الكعكة ثانيتين.

ملخص شجرة التجوال الفرعية (roam subtree):

  1. سيقوم المحدد (Selector) بتشغيل الشجرة الفرعية للتجوال (roam subtree) إذا فشلت الشجرة الفرعية للهجوم (attack subtree)، وفي هذه الحالة، ستفشل إذا لم يتم تعيين العدو (Enemy).
  2. ستنشئ (BTService_SetRandomLocation) موقعاً عشوائياً.
  3. سوف تنتقل الكعكة إلى الموقع الذي تم إنشاؤه.
  4. بعد ذلك، سوف تنتظر لمدة خمس ثوان.

أغلق (BT_Muffin) ثم اضغط على تشغيل (Play)، وقم بتوليد بعض الكعك واستعد للمعركة الملكية الأكثر دموية على الإطلاق!

الشكل النهائي للعبة

المصدر
هنا

مقالات ذات صلة

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني.