اذهب إلى المحتوى

برمجة لعبة متاهة باستخدام محرك يونيتي Unity


أروى عفان

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

step1_gameScreenshot.png

سنتعلم في هذا المشروع ما يلي:

  • كيفية إنشاء أشكال ثلاثية الأبعاد.
  • كيفية تغيير لون وحجم وموضع الكائنات.
  • كيفية تعديل طريقة عرض اللعبة بحيث تتبع حركة اللاعب.
  • كيفية إضافة شيفرة برمجية إلى الكائنات للتحكُّم في حركتها وتصرفاتها.

ستحتاج في هذا المشروع إلى:

  • عتاد: حاسوب يعمل بنظام ويندوز أو ماك، قادر على تشغيل يونيتي.
  • برمجيات: محرر يونيتي، ويفضل تنصيبه مع تطبيق Unity Hub، الذي يتيح لك تثبيت عدة إصدارات من محرر يونيتي وإدارة الإضافات extensions. قد تستغرق عملية التنزيل وقتًا طويلًا نظرًا لحجم البرنامج الكبير نسبيًا، لذلك ننصحك بتنزيله وتنصيبه قبل بدء المشروع.

إعداد المشروع

أولًا، افتح محرر يونتي وانقر علىNew لإنشاء مشروع جديد:

New_Unity.png

ثانيًا، سمِّ المشروع "Beginner Unity Sushi"، أو أي اسمٍ آخر تفضله، ثم انقر على خيار إنشاء المشروع Create Project وانتظر إلى أن يظهر مشروعك على الشاشة.

ثالثًا، انقر على قائمة تخطيط الصفحة Layout الموجودة أعلى الزاوية اليمنى للشاشة، ثم اختر الوضع الافتراضي Default.

step3_layout.png

رابعًا، تأكد من وجود مجلد المشاهد "scenes" في نافذة الممتلكات Assets؛ وفي حال عدم وجوده، أنشِئه عن طريق النقر على شريط القائمة menu الموجود أعلى القائمة، ثم النقر على شريط الممتلكات Assets الموجود في اليسار. انقر بعدها على خيار إنشاء Create، ثم على مجلد Folder، وسمّ المجلد "scenes".

step3_scenes.png

خامسًا، حان الآن وقت حفظ المشهد الأولي المرفق مع المشروع وذلك من القائمة العلوية بالنقر على ملف File، ثم احفظ المشهد باسم Save Scene as وسمّه "MazeRoboBegins" واحفظه في مجلد المشاهد "scenes" ضمن مجلد "Assets".

ننصحك بحفظ المشروع بعد كل تعديلٍ تجريه عليه، وذلك بالنقر على File من القائمة أعلى الشاشة، ثم النقر على خيار Save Scenes، كما يمكنك اختصارًا النقر على مفتاحي Ctrl و S في أجهزة الويندوز، ومفتاحي Cmd و S في أجهزة ماك.

إنشاء الشخصية الرئيسية

ستكون الشخصية الرئيسية في لعبتنا عبارة عن رجل آلي نتحكم في حركته ضمن المتاهة، ولكن علينا تصميمه أولًا! أولًا، اصنع جسم الرجل الآلي بحيث يكون له شكل الكبسولة، وذلك بالنقر على الخيارات التالية بالترتيب: GameObject > 3D Object > Capsule.

step4_capsule.png

ثانيًا، انقر على جسم الرجل الآلي، وستظهر لك نافذة وحدة المراقب Inspector، حيث يمكنك إعداد الكائنات وتغيير خصائصها. سمِّ الكبسولة "MazeRobo" بكتابة اسم الكائن أعلى نافذة المراقب inspector كما هو موضح أدناه:

InspectorWindow.png

ثالثًا، انقر على رمز المسنن في مربع التحويل Transform في نافذة وحدة المراقب، ثم اختر إعادة الضبط Reset وذلك لوضع الكائن في منتصف منصة العرض.

step4_Transform.png

رابعًا، لا زلنا بحاجةٍ إلى مزيد من الأشكال لتكوين رجلنا الآلي. لذلك، أضف مكعبًا Cube بالنقر على الخيارات التالية GameObject > 3D Object > Cube ثم أضف كرةً على النحو التالي: GameObject > 3D Object > Sphere، ثم غيِّر اسم المكعب إلى "Shades" والكرة إلى "Nose".

خامسًا، لاحظ ظهور الكائنات الثلاثة ضمن قائمة على يسار الشاشة، انقر على الكائن "Nose" واسحبه ثم أفلته فوق "MazeRobo" كي يتحرك بحركته، وافعل المثل مع الكائن "Shades"، كما هو موضح أدناه:

step4_moveObjects.png

step4_afterMove.png

وبهذه الطريقة يمكننا تجميع الاشكال والحصول على شخصيات متكاملة من أشكال بسيطة.

سادسًا، انقر على الكائن "Shades" ولاحظ وجود ثلاث إحداثيات (X, Y, Z) في نافذة المراقب inspector في قسم Transform تتحكم بموضع الكائن.

غَيّر قيم الإحداثيات وشاهد ما الذي سيحدث، وضَع الرمز ~ أمام بعض القيم، ثم اعتمد القيم التالية:

X = 0
Y = 0.64
Z = 0.42

step4_TransformPosition.png

سابعًا، أسند قيم الإحداثيات التالية للكائن "Nose":

X = 0
Y = 0.5
Z = 0.5

الآن، يجب علينا تعديل شكل الكائنين لنحصل على شكلٍ مشابهٍ للرجل الآلي، وذلك بتعديل الحجم Scale وفقًا للقيم التالية للكائن "Shades":

X = 0.64
Y = 0.16
Z = 0.16

step4_TransformScale.png

والقيم التالية للكائن "Nose":

X = 0.16
Y = 0.16
Z = 0.16

ليصبح لدينا الرجل الآلي التالي:

step4_robot.png

تلوين الرجل الآلي

أولًا، أنشئ مجلدًا جديدًا بالنقر على الخيارات التالية بالترتيب: Assets > Create > Folder، انقر بالزر الأيمن للفأرة عليه ثم انقر على خيار إعادة التسمية Rename وسمّه "Materials".

step5_rename.png

ثانيًا، أنشئ مادتين جديدتين بالنقر على Assets > Create > Material وسمّهما "EyeBlack" و "NoseRed". لاحظ ظهور المادتين اللتين أنشأتهما في مجلد المواد "Materials" في نافذة المشروع Project أسفل الشاشة، وفي حال وجدتهما خارجه، فاسحبهما إلى داخل المجلد "Materials".

step5_materialsFolder.png

يمكن تغيير لون مادة ما عن طريقة تغيير قيمة بياضها albedo في نافذة المراقب inspector، بالنقر على المستطيل الأبيض بجانب أداة اختيار اللون، ثم انتقاء اللون المناسب.

colour_picker.png

ثالثًا، اختر اللون الأسود لمادة العين "EyeBlack" والأحمر لأنف الرجل الآلي "NoseRed".

رابعًا، انقر على الكائن "Shades" ثم انقر على خيار the Materials في قسم Mesh Renderer، وانقر بعدها على الدائرة الصغيرة بجانب العنصر "0 Element" واختر منها "EyeBlack".

الآن، أصبح لدى الرجل الآلي نظارات شمسية سوداء.

step5_chooseMaterial.png

خامسًا، كرِّر الخطوة السابقة واختر "NoseRed".

الآن، أصبح لدى الرجل الآلي نظارات شمسية وأنف أحمر.

step5_mazeRoboInColour.png

التحكم بالرجل الآلي

يجب عليك إضافة مكوّن الجسم الصلب RigidBody لتتمكن من تحريك الرجل الآلي.

أولًا، انقر على الرجل الآلي، ثم على Component > Physics > Rigidbody للتحكم بالرجل الآلي في اللعبة.

لاحظ أنه عند النقر على الرجل الآلي سيظهر قسم الجسم الصلب RigidBody في نافذة المراقب Inspector. انقر على قسم القيود Constraints لفتحه، ثم فعّل خيار تثبيت الدوران Freeze Rotation على محاور الإحداثيات الثلاث، وفعّل تثبيت الموقع Freeze Position على محور Y فقط.

step5_RigidbodyConstraints.png

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

إنشاء عالم اللعبة

سنعمل في هذه الخطوة على إنشاء عالم اللعبة، أو المنصة التي سيتحرك عليها الرجل الآلي. أولًا، أضف الكائن Quad ليكون بمثابة الأرضية للعبة، وذلك بالنقر على الخيارات التالية: GameObject > 3D Object > Quad، وسمِّ الكائن "Ground" أي أرضية.

ثانيًا، اضبط قيمة الدوران على محور X على القيمة 90 في مربع التحويل Transform في نافذة المراقب ثم عدّل الحجم للكائن Scale وفق القيم التالية:

X = 40.96
Y = 40.96

Z = 1

step6_groundTransform.png

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

ثالثًا، عدّل إحداثيات الموضع للرجل الآلي من نافذة التحويل Transform وفقًا لما يلي:

X = 0
Y = 1
Z = 0

step6_MazeRoboOnGround.png

رابعًا، أضف مكعبًا Cube بالنقر على الخيارات التالية GameObject > 3D Object > Cube ليكون بمثابة حائطٍ في المتاهة، ثم أسند إليه إحداثيات الموضع التالية:

X = -2
Y = 1.5
Z = 0

خامسًا، غيّر مقياس الحجم Y Scale للكائن الجديد إلى القيمة 3، ثم سمِّ الكائن "Wall".

سادسًا، أنشئ مادةً جديدةً للحائط Assets > Create > Materials وغيّر قيمة البياض albedo لإعطائها اللون الأزرق، ثم سمّها "WallBlue".

سابعًا، أسند المادة الزرقاء "WallBlue" للحائط "Wall" عن طريق سحبها وإفلاتها فوق الحائط، أو من خيار MeshRender > Materials من نافذة المراقب.

سنعمل في الخطوات التالية على تحويل هذا الحائط إلى متاهة.

step6_Wall.png

تحريك الرجل الآلي

سنكتب، في هذه الخطوة، الشيفرة اللازمة لتحريك الرجل الآلي.

أولًا، أنشئ مجلدًا جديدًا من نافذة المشروع Project بالنقر على Assets > Create > Folder، وسمِّ المجلد "Scripts".

step7_ScriptsFolder.png

ثانيًا، أنشئ مجلدًا داخل مجلد Scripts لكتابة الشيفرة بلغة #C بالنقر على Assets > Create > C# Script وسمّه "RoboMover".

step7_NewScript.png

ثالثًا، انقر مزدوجًا على مجلد RoboMover لفتحه في المحرر ولاحظ أنك ستحصل على الشيفرة التالية:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RoboMover : MonoBehaviour {

  // تُستخدم هذه الدالة للتهيئة

  void Start () {

  }

//تُستدعى دالة التعديل مرةً واحدةً عند تصيير كل إطار

  void Update () {

  }
}

لنلقي نظرةً معمقةً على الشيفرة لنفهم آلية عملها:

تهيئ الأسطر الثلاثة الأولى البرنامج للعمل.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

يُعّرف السطر التالي الصنف RoboMover من النوع العام public وتُكتب محتويات الصف داخل القوسين { }.

public class RoboMover : MonoBehaviour {

صرّحنا بعدها عن دالتين هما دالة البدء Start ودالة التعديل Update، ولاحظ أنهما فارغتان الآن، إذ سنُعدّلهما فيما بعد:

void Update() {

}

الدالة Function: هي مجموعةٌ من التعليمات موجهةٌ للحاسوب ليُنفذ أمرًا ما، وتُسمى باسمٍ يدل على عملها. فعلى سبيل المثال، كثيرًا ما نستخدم الأمر "أعّد لي كوبًا من الشاي" في حياتنا اليومية والذي يماثل الدالة، إذ يعلم هنا الشخص الخطوات اللازمة لتحضير كوب الشاي وليس علينا تذكيره بها في كل مرة، فقط علينا ذكر الأمر؛ وكذلك الأمر بالنسبة للحاسوب، يكفي ذكر الأمر أو الدالة مع خطوات التنفيذ مرةً واحدةً، ثم نكتفي بعدها باستدعاء الدالة عن طريق ذكر اسمها فقط.

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

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

رابعًا، أضف الأسطر التالية على الشيفرة داخل الصنف، واحذف دالة البدء () void Start لأننا لن نحتاجها:

public class RoboMover : MonoBehaviour {

  public float moveSpeed = 4.0f;
  public Rigidbody rb;
  public Transform tf;

أضفنا ثلاثة متغيرات variables على الشيفرة لتسهيل استدعاء ما تدل عليه، إليك شرحًا موجزًا لعملها:

  • المتغير moveSpeed: يدل على سرعة الحركة وهو رقم عشري من النوع العائم Float (عدد عشري).
  • المتغير rb: يدل هذا المتغير إلى مركبة الجسم الصلب للرجل الآلي.
  • المتغير tf: يشير هذا المتغير إلى مكون التحويل Transform.

خامسًا، أضف الأسطر التالية إلى دالة التعديل Update:

// تُستدعى دالة التعديل مرةً واحدةً عند لكل إطار

void Update () {
  Vector3 desiredDirection = new Vector3 (Input.GetAxis ("Horizontal"), 0.0f, Input.GetAxis ("Vertical"));
  desiredDirection = moveSpeed * desiredDirection;
  desiredDirection = Time.deltaTime * desiredDirection;
  rb.MovePosition (rb.position + desiredDirection);
}

يُنشئ السطر الأول شعاعًا للمسافة المطلوبة desiredDirection، وهو مكونٌ من ثلاث مركبات للإحداثيات، اثنتان منهما للاتجاهات التي يدخلها اللاعب Input، والمركبة الثالثة هي العمق depth وقيمتها ثابتة 0.0.

بعدها نضرب المسافة desiredDirection بمتغير السرعة moveSpeed، ثم نضرب المسافة desiredDirection بالمتغير Time.deltaTime والذي يشير للزمن منذ آخر عملية تعديل، ما يضمن أن الإحداثيات تتغير بدقة مهما كان نوع الجهاز الذي يُشغِّل اللعبة.

إذًا، سيتحرك الرجل الآلي "MazeRobo" من خلال القيمة المحسوبة والمُخزنة في desiredDirection بالإتجاه الذي نحدّده وبخطوات صغيرة، عند كل تحديثٍ للشاشة.

لا تنسى حفظ الشيفرة بالنقر على قائمة ملف File، ثم على حفظ Save. سادسًا، اسحب ملف الشيفرة RoboMover وأفلته فوق كائن MazeRobo في القائمة التسلسلية Hierarchy، كما هو موضح أدناه:

step7_dragScript.png

سيظهر قسم خاص بالشيفرة "RoboMover" في نافذة المراقب أسفل قسم الجسم الصلب "Rigidbody":

MazeRobo_Inspector.png

لاحظ وجود حقلين فارغين في قسم "RoboMover" هما rb و tf الذين يشيران إلى الجسم الصلب Rigidbody والتحويل Transform على الترتيب. انقر عليهما واسحبهما إلى الحقلين الفارغين كي تحصل على القيم المطلوبة لتحريك الرجل الآلي:

step7_DragOntoScript.png

Script_Vars.png

أصبحت الآن جاهزًا للعب. انقر على زر اللعب Play الموجود في منتصف واجهة يونيتي، واستخدم مفاتيح الأسهم لتحريك الرجل الآلي، وانقر على زر Play مرةً أخرى لإيقاف اللعبة.

تحسين الحركة

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

أولًا، أضف السطر التالي على الشيفرة تحت دالة rb.MovePosition:

rb.MoveRotation (Quaternion.LookRotation (desiredDirection, Vector3.up));

إذ يجعل هذا السطر الرجل الآلي MazeRobo ينظر إلى وجهته.

ثانيًا، شغّل اللعبة وتحقق من حركة الرجل الآلي.

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

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

ثالثًا، ضع جزء الشيفرة المتعلق بالإتجاه داخل تعليمة if ليُنفَّذ عند تحقق الشرط. سنغير الشرط فيما بعد، لكن اجعله الآن محققًا دائمًا بتمرير القيمة true مكان الشرط:

// تُستدعى دالة التعديل مرةً واحدةً لكل إطار

void Update () {

    if (true) {
      Vector3 desiredDirection = new Vector3 (Input.GetAxis ("Horizontal"), 0.0f, Input.GetAxis ("Vertical"));
      desiredDirection = moveSpeed * desiredDirection;
      desiredDirection = Time.deltaTime * desiredDirection;
      rb.MovePosition (rb.position + desiredDirection);
      rb.MoveRotation (Quaternion.LookRotation (desiredDirection, Vector3.up));
    }
}

الآن، شغّل اللعبة مرةً أخرى وتحقق من حركة الرجل الآلي.

رابعًا، أضف الأسطر التالية على دالة التعديل Update للحصول على القيمة المطلقة absolute value لمدخلات اللاعب، أي قيمة الرقم دون إشارته:

void Update () {

float inputHorizontal = Mathf.Abs (Input.GetAxis ("Horizontal"));
float inputVertical = Mathf.Abs (Input.GetAxis ("Vertical"));

if (true) {

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

الآن، علينا تعديل شروط تعليمة if بحيث تتحقق فيما إذا كانت قيمة inputHorizontal أكبر من 0.01 أو إذا كانت قيمة inputVertical أكبر من 0.01، وسنحتاج إلى استخدام العامل أو orوالذي نمثله باستخدام شرطتين عموديتين || في لغة سي شارب #C، إذ تُوضع الشرطتين بين الحالتين اللتين نود التحقق منهما، كما يلي:

condition A || condition B

أما للعامل و فنستخدم الرمز التالي "&&".

عدّل تعليمة if لتبدو كما يلي:

if (inputHorizontal > 0.01f || inputVertical > 0.01f) {

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

void Update () {

  float inputHorizontal = Mathf.Abs (Input.GetAxis ("Horizontal"));
  float inputVertical = Mathf.Abs (Input.GetAxis ("Vertical"));

  if (inputHorizontal > 0.01f || inputVertical > 0.01f) {
    Vector3 desiredDirection = new Vector3 (Input.GetAxis ("Horizontal"), 0.0f, Input.GetAxis ("Vertical"));
    desiredDirection = moveSpeed * desiredDirection;
    desiredDirection = Time.deltaTime * desiredDirection;
    rb.MovePosition (rb.position + desiredDirection);
    rb.MoveRotation (Quaternion.LookRotation (desiredDirection, Vector3.up));
    }

step8_RoboFacingCamera.png

ملاحقة الكاميرا

سنعمل في هذه الخطوة على تعديل نطاق عرض الكاميرا بحيث تلاحق حركة الرجل الآلي.

أولًا، انقر على الكاميرا الرئيسية Main Camera في نافذة القائمة التسلسلية Hierarchy من نافذة المراقب inspector، وأسند القيم التالية لمركبة الموضع، والدوران، والحجم، بالترتيب:

step9_SelectMainCamera.png

  • الموضع:
X: 0
Y: 9
Z: -5
  • الدوران:
X: 60
Y: 0
Z: 0
  • الحجم:
X: 1
Y: 1
Z: 1

step9_MainCameraTransform.png

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

ثانيًا، أنشئ مجلدًا جديدًا لحفظ الشيفرة داخل مجلد Scripts بالنقر على Assets > Create > C# Script وسمّه "CameraMover".

أضف المتغيرات الثلاث التالية داخل الصنف CameraMover:

public class CameraMover : MonoBehaviour {

  public Transform tf;
  public Transform playerTransform;
  public Vector3 distanceBetweenPlayerAndCam;

تتبِّع الأسطر السابقة التي أضفناها حركة ما يلي:

  • موضع الكاميرا tf.
  • موضع الرجل الآلي playerTransform.
  • إحداثيات الموضع بين الكاميرا والرجل الآلي distanceBetweenPlayerAndCam.

ثالثًا، حدِّد المسافة الابتدائية بين الكاميرا والرجل الآلي بإضافة السطر التالية على دالة البدء Start:

void Start () {
  distanceBetweenPlayerAndCam = tf.position - playerTransform.position;
}

رابعًا، أضف السطر التالي لدالة Update للحفاظ على المسافة ذاتها في كل الإطارات:

void Update () {
  tf.position = playerTransform.position + distanceBetweenPlayerAndCam;
}

خامسًا، أضف الشيفرة للكاميرا، وذلك بالنقر على خيار الكاميرا الأساسية Main Camera من القائمة، ثم اسحب شيفرة الصنف CameraMover وأفلتها فوق الكاميرا، ثم انقر على خيار الكاميرا الأساسية Main Camera من القائمة واسحبه إلى الحقل "Tf" في نافذة المراقب، واسحب MazeRobo إلى الحقل "Player Transform"، كما هو موضح أدناه:

step9_dragFromHierarchyOntoScript.png

والآن، شغّل اللعبة ولاحظ كيف تلاحق الكاميرا حركة الرجل الآلي.

step9_CameraFollowing.png

إضافة مزيد من العناصر

سنضيف الآن كرةً على المتاهة ليلعب بها الرجل الآلي.

أولًا، أنشئ كرةً بالنقر على GameObject > 3D Object > Sphere وسمّها "Ball".

ثانيًا، أسند القيم التالية لموضع الكرة:

X: 0
Y: 1
Z: 2

ثالثًا، أنشئ مادةً لونها أخضر وسمّها "BallGreen"، ثم طبِّقها على الكرة بسحبها وإفلاتها عليها.

step10_AddGreenBall.png

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

رابعًا، انقر على الكرة وفعّل خيار الجسم الصلب Rigidbody وذلك من Component > Physics > Rigidbody.

الآن، شغّل اللعبة واختبر حركة الكرة.

step10_RollingBall.png

الفوز

بعد أن أصبحت لدينا العناصر الرئيسية للعبة جاهزةً، علينا أن نحدد طريقةً للفوز.

أولًا، أضف مكعبًا وسمّه "WinZone" ولوّنه بلونٍ مناسب، ثم حدِّده من القائمة التسلسلية وانقر لتحديد خيار Is Trigger من قسم Box Collider من نافذة المراقب:

step11_BoxColliderTrigger.png

ثانيًا، أسند القيم التالية لموضع المكعب الجديد:

X: -5
Y: 1
Z: -2

الآن سنكتب شيفرةً تتيح للمكعب "WinZone" التحسُّس للكرة عندما تلمسه، لذلك يجب علينا وضع علامة على الكرة.

ثالثًا، انقر على الكرة في القائمة التسلسلية، ثم انقر على خيار الوسم Tag في نافذة المراقب:

step11_BallTagProperty.png

رابعًا، انقر على خيار إضافة وسم Add Tag ثم انقر على الرمز + لإضافة وسمٍ جديد وسمّه "Ball".

step11_AddTag.png

step11_NewTagBall.png

خامسًا، انقر مرةً ثانيةً على الكرة في القائمة التسلسلية، ثم انقر على حقل الوسم Tag في نافذة المراقب مرةً ثانية واِختر الوسم الجديد الذي أضفناه.

step11_ChooseBallTag.png

الآن، سنضيف بعض المؤثرات للاحتفال بفوز اللاعب.

سادسًا، أنشئ Particle System بالنقر على GameObject > Effects > Particle System وسمّه "Fireworks" أي ألعاب نارية.

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

step11_uncheckFireworks.png

ثامنًا، اختر اللون الأولي Start Color للألعاب النارية من نافذة المراقب، ثم أسند لإحداثيات الموضع قيمًا مطابقةً لقيم المكعب "WinZone".

تاسعًا، أنشئ مجلدًا داخل مجلد Scripts لكتابة الشيفرة بلغة #C وسمّه WinZone، ثم امسح منه دالتي Start و Update وأضف عليه الشيفرة التالية:

public GameObject fireworks;

void OnTriggerEnter (Collider col) {
  if (col.transform.CompareTag ("Ball")) {
    fireworks.SetActive (true);
  }
}

تتحقق الشيفرة المُضافة من ملامسة أي جسم صلب للمكعب "WinZone" وتسند المتغير col للجسم الصلب، أما إذا كان الجسم الصلب هو الكرة، فسيظهر الكائن fireworks لتنطلق الألعاب النارية.

عاشرًا، احفظ ملف الشيفرة ثم اسحبه وأفلته فوق WinZone في القائمة التسلسلية، ثم انقر على WinZone واسحب كائن الالعاب النارية الموجود أدناه إلى قسم الألعاب النارية "fireworks" في نافذة المراقب، كما هو موضح:

step11_DragFireworksIntoScript.png

step11_FireworksInScript.png

أخيرًا، احفظ اللعبة ثم شغّلها واستمتع بتجربة اللعبة التي أنشأتها.

step11_WinningFireworks.png

ترقية اللعبة

لاحظ أن المتاهة التي أنشأناها ليست مكتملة، ومهمتك الآن هي العمل على إكمالها وإضافة مزيدٍ من المكعبات وتعديل مركبات الحجم والموضع لتكون بمثابة جدران للمتاهة، ووضع مكعب الفوز في مكان يصعُب الوصول إليه.

لا تنسى مشاركة اللعبة مع أصدقائك.

خاتمة

بهذا تكون قد أنشأت لعبتك الأولى على محرك الألعاب الشهير يونتي، تهانينا.

ننصحك بالاستمرار والإطلاع على دروس صناعة الألعاب باستخدام يونيتي الموجودة على أكاديمية حسوب.

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

ترجمة -وبتصرف- للمقال Robot maze من الموقع الرسمي لراسبيري باي.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...