جدول المحتويات:

كيف تصنع لعبة متعددة اللاعبين باستخدام وحدات تحكم Arduino: 6 خطوات
كيف تصنع لعبة متعددة اللاعبين باستخدام وحدات تحكم Arduino: 6 خطوات

فيديو: كيف تصنع لعبة متعددة اللاعبين باستخدام وحدات تحكم Arduino: 6 خطوات

فيديو: كيف تصنع لعبة متعددة اللاعبين باستخدام وحدات تحكم Arduino: 6 خطوات
فيديو: نارين بيوتي قبل وبعد عملية التجميل 🤯 2024, يونيو
Anonim
كيف تصنع لعبة متعددة اللاعبين باستخدام وحدات تحكم Arduino
كيف تصنع لعبة متعددة اللاعبين باستخدام وحدات تحكم Arduino

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

اللوازم

سوف تحتاج:

  • كمبيوتر محمول
  • محرك الوحدة
  • C # IDE يعمل مع Unity مثل الاستوديو المرئي أو Atom. (سأستخدم Visual Studio Code)
  • 2X اردوينو نانو
  • 2X لوح خبز كبير
  • 2X لوح خبز صغير
  • 4X Tack Switch (زر ضغط)
  • 4X 200Ω المقاوم
  • 12X ذكر إلى ذكر أسلاك العبور
  • اردوينو IDE

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

رابط تحميل Unity Engine:

store.unity.com/download-nuo

رابط لتنزيل Visual Studio Code IDE:

code.visualstudio.com/download

رابط تنزيل Arduino IDE:

www.arduino.cc/en/Main/Software

الخطوة 1: قم بإعداد حدود اللعبة

قم بإعداد حدود اللعبة
قم بإعداد حدود اللعبة
قم بإعداد حدود اللعبة
قم بإعداد حدود اللعبة
قم بإعداد حدود اللعبة
قم بإعداد حدود اللعبة

بادئ ذي بدء ، تحتاج إلى تنزيل الوحدة

بمجرد الانتهاء من ذلك ، يمكنك البدء في إعداد عرض لعبتك.

افتح مشروع Unity جديدًا ، وقم بتسميته وحدد لعبة ثنائية الأبعاد.

عند فتح المشروع ، لاحظ أن هناك 3 أقسام رئيسية تسمى

  • التسلسل الهرمي (هذا هو المكان الذي ستتم فيه إضافة جميع عناصر وتفاصيل اللعبة).
  • المشهد (حيث تقوم بإعداد عرض اللعبة).
  • لعبة (حيث يمكنك اختبار كيف ستصبح اللعبة الحقيقية).

لاحظ أنه يوجد تحت التسلسل الهرمي مشهدك وتحت المشهد توجد "الكاميرا الرئيسية". عند تحديد الكاميرا من التسلسل الهرمي ، سيتم تحديدها في المشهد

(أي شيء داخل حدود هذه الكاميرا سيظهر في اللعبة الحقيقية).

انظر إلى الصورة 1

تتكون لعبتنا من لوحين ، كرة تتحرك حولها ، وحدود تحد من حركة الألواح والكرة.

لنبدأ بإنشاء الحدود.

  1. لإنشاء كائن لعبة جديد ، حدد Assets> Create> Sprites> square (أطلق عليها اسم "الحدود اليمنى واليسرى") انظر إلى الصورة 2
  2. اسحب الحدود اليمنى واليسرى وأفلتها في التسلسل الهرمي وسيظهر مربع في المشهد.
  3. اضبط موضع المحور x على (5) "الحدود اليمنى واليسرى"> المفتش> التحويل> الموضع> X. انظر إلى الصورة 3
  4. ثم اضبط مقياسه بحيث يكون كبيرًا بما يكفي لتغطية حدود الكاميرا (اسحب الجانبين العلوي والسفلي للمربع لتمديده).
  5. اضبط لونه "من الحدود اليمنى واليسرى"> المفتش> عرض الرموز> اللون. انظر إلى الصورة 3
  6. قم بالتمرير لأسفل في المفتش وحدد إضافة مكون ثم اكتب Rigidbody2D واضغط على إدخال ، وهذا سيضيف الفيزياء إلى كائن لعبتك لأنه يمنحه الكتلة والجاذبية واكتشاف الاصطدام. ومع ذلك ، لا نحتاج إلى الجاذبية في لعبتنا ، لذا اجعل الجاذبية 0 بدلاً من 1. ستحتاج أيضًا إلى تجميد الموضع والدوران حتى لا تتحرك الحدود عند الاصطدام. انظر إلى الصورة 4
  7. حدد إضافة مكون ثم اكتب Box Collider 2D واضغط على Enter ، وسيضيف هذا منطقة حول كائن اللعبة حيث يمكن اكتشاف التصادمات. انظر إلى الصورة 4
  8. حدد الآن الحدود اليمنى واليسرى واضغط (ctrl + d) لتكرارها.
  9. أعد تسميته "الحد الأيسر" وأعد تسمية الحد الأول ("الحد الأيمن").
  10. حدد الحد الأيسر واضبط موضع المحور x الخاص به إلى (-5) بنفس الطريقة في الخطوة 3. الآن لديك الحدود اليمنى واليسرى.

كرر الخطوات العشر السابقة مع الحدود لأعلى ولأسفل وقم بتغيير موضع المربع y بدلاً من موضع x. يجب أن تكون المعاينة النهائية مشابهة لتلك الموجودة في الصورة.

انظر إلى الصورة 5

الخطوة الثانية: إضافة اللوحات وعمل وحدات التحكم

إضافة لوحات وعمل وحدات تحكم
إضافة لوحات وعمل وحدات تحكم
إضافة لوحات وعمل وحدات تحكم
إضافة لوحات وعمل وحدات تحكم
إضافة لوحات وعمل وحدات تحكم
إضافة لوحات وعمل وحدات تحكم

إضافة المجالس

قم بإنشاء كائن لعبة جديد وقم بتسميته لاعب 1.

يعدل:

  • المقياس: X (1.2) ، Y (0.15) ، Z (1)
  • المركز: X (0) ، Y (-3.6) ، z (0)
  • أضف BoxCollider2D
  • أضف Rigidbody 2D وقم بتجميد محوري y و z.

كرر (ctrl + d) وأعد تسمية مشغل النسخ 2.

يعدل:

  • المقياس: X (1.2) ، Y (0.15) ، Z (1)
  • المركز: X (0) ، Y (3.6) ، z (0)
  • سيكون BoxCollider موجودًا بالفعل.
  • سيكون هناك Rigidbody 2D بالفعل وسيتم تجميد محوري y و z بالفعل.

انظر إلى الصورة 1

صنع وحدات تحكم

سوف تحتاج:

  • 2X اردوينو نانو
  • 2X لوح خبز كبير
  • 2X لوح خبز صغير
  • 4X Tack Switch (زر ضغط)
  • 4X المقاوم
  • 12X ذكر إلى ذكر أسلاك العبور

انظر الآن إلى صور لوحة الخبز ورسم الخرائط لتجميع أذرع التحكم.

  1. إرفاق شريحة Arduino Nano واحدة بلوحة خبز صغيرة.
  2. قم بإرفاق مفتاحي Tack على لوحة الخبز الكبيرة كما هو موضح في الصورة. حاول أن تحافظ على الجانب الأيمن من لوحة الخبز متناسقًا مع اليد اليسرى لأن هذا سيجعل عصا التحكم تبدو أفضل (يمكنك استخدام العمود 30 كتماثل خط)
  3. قم بتوصيل الدبوس العلوي الأيسر للزر الأيسر بدبوس 5 فولت في Arduino على لوح الخبز الصغير (الأشياء المتصلة بنفس العمود في لوح التجارب متصلة ببعضها البعض).
  4. قم بتوصيل الدبوس العلوي الأيمن للزر الأيمن مع دبوس 5V في Arduino.
  5. قم بتوصيل الدبوس السفلي الأيمن للزر الأيسر بنقطة على العمود الحادي والثلاثين باستخدام المقاوم.
  6. قم بتوصيل الدبوس السفلي الأيسر للزر الأيمن بنقطة على العمود التاسع والعشرين باستخدام المقاوم.
  7. قم بتوصيل المقاومات بدبوس GND في Arduino.
  8. قم بتوصيل الدبوس العلوي الأيمن للزر الأيسر بدبوس D3 في Arduino.
  9. قم بتوصيل الدبوس العلوي الأيسر للزر الأيمن بدبوس D9 في Arduino.
  10. كرر الآن هذه الخطوات وقم بعمل وحدة التحكم الثانية.

الخطوة 3: توصيل Arduino بالمنفذ التسلسلي

توصيل Arduino بالمنفذ التسلسلي
توصيل Arduino بالمنفذ التسلسلي
توصيل Arduino بالمنفذ التسلسلي
توصيل Arduino بالمنفذ التسلسلي
توصيل Arduino بالمنفذ التسلسلي
توصيل Arduino بالمنفذ التسلسلي
توصيل Arduino بالمنفذ التسلسلي
توصيل Arduino بالمنفذ التسلسلي

أولاً ، ستحتاج إلى تثبيت Arduino IDE.

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

الآن دعنا نربط Arduino بالمنفذ التسلسلي.

أنظر إلى الصور

  1. قم بتوصيل Arduino بجهاز الكمبيوتر المحمول الخاص بك
  2. أدوات> لوحة> Arduino Nano
  3. إذا كانت شريحة Arduino الخاصة بك حديثة (2018-2020) ، فالأدوات> المعالج> ATmega328P (أداة تحميل التشغيل القديمة).
  4. إذا لم تكن شريحة Arduino الخاصة بك حديثة (قبل 2018) ، فالأدوات> المعالج> ATmega328P
  5. أدوات> منفذ> COM (أي رقم يظهر ، في حالتي هو 10). * هذا هو المنفذ التسلسلي حيث سيتم تخزين القيم.
  6. انسخ الكود والصقه في Arduino IDE واضغط على ctrl + u لتحميل البرنامج.
  7. كرر مع Arduino الثاني. (عند تنفيذ الخطوة 5 ، تأكد من اختيار منفذ COM آخر بحيث لا يتم توصيل كل من وحدات التحكم بنفس المنفذ التسلسلي).

الشفرة:

الإعداد باطل() {

Serial.begin (9600) ؛ pinMode (3 ، الإدخال) ؛ // إخبار Arduino بتلقي إدخال من pin D3 pinMode (9 ، INPUT) ؛ // إخبار Arduino بتلقي إدخال من pin D9} void loop () {if (digitalRead (3) == 1) {/ * إذا تلقى Arduino إدخالًا من 1 Serial.write (1) ؛ من الطرف 3 قم بإخراج القيمة 1 إلى المنفذ التسلسلي Serial.flush () ؛ * / تأخير (2) ؛ } if (digitalRead (9) == 1) {/ * إذا تلقى Arduino إدخالاً من 1 Serial.write (2) ؛ من الطرف 9 قم بإخراج القيمة 2 إلى المنفذ التسلسلي Serial.flush () ؛ * / تأخير (2) ؛ }}

شرح البرنامج:

يأخذ هذا الرمز ببساطة إدخالًا من دبوس D3 ودبوس D9 في Arduino ، والمتصلين بالأزرار. الأزرار إما مضغوطة أو غير مضغوطة مما يعني أن القراءات المأخوذة منها إما 1 (مضغوط) أو 0 (غير مضغوطة). إذا كان الإدخال من الزر الأيمن (من D9) هو 1 (مضغوط) ، قم بتخزين القيمة 1 في المنفذ التسلسلي. إذا كان الإدخال من الزر الأيسر (من D3) هو 1 (مضغوط) ، قم بتخزين قيمة 2 في المنفذ التسلسلي.

الخطوة 4: توصيل الوحدة بالمنفذ التسلسلي

توصيل الوحدة بالمنفذ التسلسلي
توصيل الوحدة بالمنفذ التسلسلي
توصيل الوحدة بالمنفذ التسلسلي
توصيل الوحدة بالمنفذ التسلسلي

في هذه الخطوة ، سنقوم بتحديد المنفذ التسلسلي في Unity حتى يتمكن من استقبال المدخلات من Arduino عند الضغط على الأزرار. قم بتثبيت Visual Studio Code على الكمبيوتر المحمول الخاص بك. ثم انتقل إلى الوحدة ، وحدد اللاعب 1 من التسلسل الهرمي ، وانتقل لأسفل وحدد إضافة مكون واكتب player1_motion ثم اضغط على إدخال. انظر إلى الصورة 1

سيتم إنشاء برنامج نصي C # في المفتش ، انقر فوقه بزر الماوس الأيمن وحدد تحرير البرنامج النصي ، ويجب فتح رمز الاستوديو المرئي وسيظهر رمزًا افتراضيًا يشبه الصورة 2.

انسخ التعليمات البرمجية التالية ثم غيّر "SerialPort sp = new SerialPort (" COM10 "، 9600)؛" مع SerialPort sp = منفذ تسلسلي جديد ("منفذ COM الذي يتصل به Arduino" ، 9600) ؛ يمكنك العثور عليه من خلال العودة إلى كود Arduino الخاص بك وأدوات goning> Port> COM (أي رقم يظهر).

الشفرة:

باستخدام System. Collections.

باستخدام System. Collections. Generic ؛ باستخدام UnityEngine ؛ باستخدام System. IO. Ports ؛ player1_motion من الفئة العامة: السلوك الأحادي {سرعة الطفو = 8 ؛ كمية تعويم خاصة تتحرك ؛ SerialPort sp = منفذ تسلسلي جديد ("COM10"، 9600) ؛ // يتم استدعاء Start قبل أول تحديث للإطار فارغ Start () {sp. Open ()؛ sp. ReadTimeout = 1 ، } // تم استدعاء التحديث مرة واحدة لكل إطار باطل Update () {amounttomove = speed * 0.01f؛ إذا (sp. IsOpen) {حاول {moveObject (sp. ReadByte ()) ؛ طباعة (sp. ReadByte ()) ؛ } catch (System. Exception) {}}} void moveObject (int Direction) {if (Direction == 1) {transform. Translate (Vector3.left * amounttomove، Space. World)؛ } إذا (الاتجاه == 2) {transform. Translate (Vector3.right * amounttomove، Space. World) ؛ }}}

شرح الكود:

يخبر هذا الرمز الوحدة لاستقبال المدخلات من المنفذ التسلسلي (COM 10). عند الضغط على الزر الأيسر ، يرسل Arduino قيمة 1 إلى المنفذ التسلسلي ، إذا استقبلت الوحدة 1 من المنفذ التسلسلي ، تتم إضافة سرعة إلى كائن اللعبة "player 1" في الاتجاه الأيسر. عند الضغط على الزر الأيمن ، يرسل Arduino قيمة 2 إلى المنفذ التسلسلي ، إذا استقبلت الوحدة 2 من المنفذ التسلسلي ، تتم إضافة سرعة إلى كائن اللعبة "player 1" في الاتجاه الصحيح. إذا لم يتلق المنفذ التسلسلي قيمة من المنفذ التسلسلي ، فلن تتم إضافة سرعة في أي من الاتجاهين ، وبالتالي ، تظل اللوحة ثابتة.

بعد نسخ الرمز ، اضغط على F5 لإنشاء التعليمات البرمجية وتشغيلها. عد إلى الوحدة واضغط على زر التشغيل ، يجب أن يتحرك اللاعب 1 إلى اليمين عند الضغط على اليمين واليسار عند الضغط على اليسار.

الآن ، قم بنفس الخطوات مرة أخرى ولكن مع المشغل 2 وتأكد من الكتابة في "إضافة مكون" player2_motion بدلاً من player1_motion وتحديد منفذ COM الثاني الذي تتصل به وحدة التحكم الثانية ، وليس نفس المنفذ التسلسلي.

ستحتاج أيضًا إلى تغيير "public class player1_motion: MonoBehaviour" إلى "public class player2_motion: MonoBehaviour" في الكود نفسه.

الخطوة 5: إضافة الكرة

مضيفا الكرة
مضيفا الكرة
مضيفا الكرة
مضيفا الكرة
مضيفا الكرة
مضيفا الكرة
  1. أضف كائنًا جديدًا للعبة ، ولكن هذه المرة اختر دائرة بدلاً من المربع.
  2. إعادة تسميتها "الكرة".
  3. السحب والإفلات في التسلسل الهرمي.
  4. اضبط المقياس (X: 0.2 - Y: 0.2 - Z: 0.2).
  5. أضف Rigidbody 2D وقم بتجميد المحور Z فقط.
  6. قم بتغيير الكتلة إلى 0.0001
  7. قم بتغيير مقياس الجاذبية إلى 0.
  8. أضف Box Collider 2D.
  9. انتقل إلى الأصول> إنشاء> مادة الفيزياء ثنائية الأبعاد انظر إلى الصورة 1
  10. غير اسمه إلى "ترتد"
  11. غير الاحتكاك إلى الصفر من المفتش
  12. قم بتغيير النطاط إلى 1 من المفتش
  13. قم بسحب وإسقاط "bounce" في Rigidbody 2D> Material. انظر إلى الصورة 2
  14. حدد "كرة" مرة أخرى من التسلسل الهرمي واذهب لإضافة مكون واكتب Ball_movement ثم اضغط على إدخال.
  15. انقر بزر الماوس الأيمن على البرنامج النصي وحدد تحرير البرنامج النصي.
  16. انسخ الكود أدناه واضغط على F5 لإنشائه وتشغيله.

الشفرة:

باستخدام System. Collections.

باستخدام System. Collections. Generic ؛ باستخدام UnityEngine ؛ فئة عامة Ball_movement: MonoBehaviour {// يتم استدعاء البداية قبل تحديث الإطار الأول قوة الطفو الخاصة = 2 ؛ void Start () {StartCoroutine (move ()) ؛ } IEnumerator move () {return return new WaitForSeconds (2)؛ GetComponent (). AddForce (جديد Vector2 (1f، 0.5f) * 0.02f * force) ؛ }}

شرح الكود

يعطي هذا الرمز الكرة سرعة في كلا الاتجاهين في اتجاه X واتجاه Y بنفس المقدار ، مما يجعل الكرة تتحرك بزاوية 45 درجة. في الخطوة 8 ، أضفنا مادة فيزيائية إلى الكرة وقمنا بتغيير ارتدادها ، وهذا يحافظ على حركة الكرة طوال اللعبة.

الخطوة السادسة: إنهاء اللعبة

إنهاء اللعبة
إنهاء اللعبة
إنهاء اللعبة
إنهاء اللعبة
إنهاء اللعبة
إنهاء اللعبة
إنهاء اللعبة
إنهاء اللعبة

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

  1. قم بسحب الكرة وإسقاطها من التسلسل الهرمي إلى المشروع ، لقد قمت بعمل قالب جاهز للكرة حتى تتمكن من استخدامه لاحقًا.
  2. انقر بزر الماوس الأيمن على التسلسل الهرمي وحدد إنشاء فارغ. سيظهر كائن فارغ ، ويعيد تسميته إلى إعادة نشر الكرة ويغير موضعه ليكون هو نفسه موضع الكرة.
  3. انقر بزر الماوس الأيمن على التسلسل الهرمي وحدد واجهة المستخدم >> نص. لاحظ أن النص مصاحب للوحة القماشية ، ويعتمد موضع النص في اللعبة على موضع النص في اللوحة ، وليس في حدود لعبتنا. (انظر إلى الصورة 1).
  4. قم بتغيير موضع النص إلى أي مكان تريده.
  5. كرر الخطوتين 3 و 4 مرة أخرى لدرجة اللاعب الثاني.
  6. اكتب في النص الأول "نتيجة اللاعب 1: 0" واكتب في النص الثاني "نتيجة اللاعب 2: 0". (انظر إلى الصورة 2).
  7. قم بإنشاء برنامج نصي في الحد الأعلى يسمى p1wins وانسخ التعليمات البرمجية التالية.

الشفرة:

باستخدام System. Collections.

باستخدام System. Collections. Generic ؛ باستخدام UnityEngine ؛ باستخدام UnityEngine. SceneManagement ؛ باستخدام UnityEngine. UI ؛ فوز p1 للفئة العامة: السلوك الأحادي {نقاط النص العامة ؛ public Transform ball_respawn ؛ الكرة GameObject العامة ؛ خاص int p1 = 0 ؛ // يتم استدعاء البداية قبل أول تحديث للإطار فارغ Start () {} // يتم استدعاء التحديث مرة واحدة لكل إطار باطل Update () {Score.text = "نقاط اللاعب 1:" + p1؛ } باطل OnCollisionEnter2D (Collision2D other) {if (other.gameObject.tag == "Ball") {Destroy (other.gameObject) ؛ p1 ++ ؛ مثيل (كرة ، ball_respawn.position ، ball_respawn.rotation) ؛ }}}

8. قم بسحب وإسقاط الكرة الجاهزة من المشروع في الخطوة 1 في معلمة الكرة. (انظر إلى الصورة 3)

9. قم بسحب وإسقاط عودة الكرة من التسلسل الهرمي إلى معلمة إعادة نشر الكرة. (انظر إلى الصورة 3)

10. قم بسحب وإفلات درجة اللاعب 1 من التسلسل الهرمي إلى معلمة النتيجة. (انظر إلى الصورة 3)

شرح الكود:

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

قم الآن بتنفيذ الخطوات 7 و 8 و 9 و 10 للحد السفلي

للخطوة 7 ، قم بإنشاء برنامج نصي يسمى p2wins وانسخ الكود التالي بدلاً من ذلك.

للخطوة 10 ، قم بسحب وإفلات درجة اللاعب 2 من التسلسل الهرمي إلى معلمة النتيجة.

الشفرة:

باستخدام System. Collections.

باستخدام System. Collections. Generic ؛ باستخدام UnityEngine ؛ باستخدام UnityEngine. SceneManagement ؛ باستخدام UnityEngine. UI ؛ p2wins للفئة العامة: السلوك الأحادي {نقاط النص العامة ؛ public Transform ball_respawn ؛ الكرة GameObject العامة ؛ خاص int p2 = 0 ؛ // يتم استدعاء البداية قبل أول تحديث للإطار فارغ Start () {} // يتم استدعاء التحديث مرة واحدة لكل إطار باطل Update () {Score.text = "نقاط اللاعب 2:" + p2؛ } باطل OnCollisionEnter2D (Collision2D other) {if (other.gameObject.tag == "Ball") {Destroy (other.gameObject) ؛ p2 ++ ؛ مثيل (كرة ، ball_respawn.position ، ball_respawn.rotation) ؛ }}}

موصى به: