تضيف خطافات القطط آليات ممتعة ومثيرة للاهتمام للعبة. يمكنك استخدامها للتحرك عبر المستويات ، والقتال في الساحات والحصول على العناصر. ولكن على الرغم من البساطة الواضحة ، يمكن أن تكون فيزياء إدارة الحبل وخلق السلوك الواقعي صعبة!
في الجزء الأول من هذا البرنامج التعليمي ، نقوم بتطبيق نظام القطط هوك ثنائي الأبعاد الخاص بنا ونتعلم ما يلي:
- إنشاء نظام تصويب.
- استخدم جهاز تقديم الخطوط ومفصل المسافة لإنشاء الحبل.
- سوف نعلم الحبل أن يلتف حول أشياء اللعبة.
- احسب زاوية التأرجح على الحبل وأضف القوة في هذا الاتجاه.
ملاحظة : هذا البرنامج التعليمي مخصص للمستخدمين المتقدمين وذوي الخبرة ، ولا يغطي موضوعات مثل إضافة المكونات ، وإنشاء نصوص GameObject جديدة ، وبناء الجملة C #. إذا كنت بحاجة إلى تحسين مهارات Unity الخاصة بك ، فراجع دروس الشروع في البدء في Unity و مقدمة في Unity Scripting . نظرًا لأنه يتم استخدام DistanceJoint2D في هذا البرنامج التعليمي ، يجب عليك أيضًا الاطلاع على وصلات الفيزياء في Unity 2D ، ثم العودة إلى هذا البرنامج التعليمي فقط.
للوصول إلى العمل
قم بتنزيل
المسودة لهذا البرنامج التعليمي ثم افتحها في محرر الوحدة. مطلوب الوحدة 2017.1 أو أعلى للتشغيل.
افتح مشهد
اللعبة من مجلد
Scenes وشاهد من أين سنبدأ:
في الوقت الحالي ، لدينا شخصية لاعب بسيط (سبيكة) وأحجار معلقة في الهواء.
المكونات المهمة في GameObject
Player حتى الآن هي مصادم الكبسولات والجسم الصلب ، مما يسمح لها بالتفاعل مع الأشياء المادية على المستوى. أيضا ، يتم إرفاق نص بسيط للحركة (
PlayerMovement ) بالشخصية ، مما يسمح لها بالانزلاق على الأرض وأداء قفزات بسيطة.
اضغط على زر التشغيل لبدء اللعبة ، وحاول التحكم في الشخصية. تحركه
A و
D يسارًا / يمينًا ، وعندما تضغط على
مفتاح المسافة ، فإنها تقفز. حاول عدم الانزلاق والسقوط من الجرف ، وإلا سوف تموت!
لدينا بالفعل أساسيات الإدارة ، ولكن المشكلة الأكبر الآن هي الافتقار إلى خطافات القطط.
إنشاء خطافات وحبال
في البداية ، يبدو نظام خطاف القطط بسيطًا للغاية ، ولكن من أجل تنفيذه عالي الجودة ، من الضروري مراعاة العديد من الجوانب. فيما يلي بعض المتطلبات لميكانيكيات القطط ثنائية الأبعاد:
- خط التقديم لعرض الحبل. عندما يلتف الحبل حول الأشياء ، يمكننا إضافة المزيد من القطع إلى جهاز تقديم الخط ووضع القمم عند النقاط المقابلة لفواصل الحبل.
- المسافة Joint2D. يمكن استخدامه لإرفاق نقطة التثبيت الحالية لخطاف القطط بحيث يمكن أن تتأرجح سلجتنا. كما يسمح لنا بتعديل المسافة التي يمكن استخدامها لإطالة الحبل وتقليله.
- Child GameObject مع RigidBody2D ، والتي يمكن تحريكها اعتمادًا على الموقع الحالي لنقطة ربط الخطاف. في الجوهر ، ستكون نقطة تعليق / ربط الحبل.
- Raycast لرمي هوك وربط الأشياء.
حدد كائن
Player في التسلسل الهرمي وقم بإضافة GameObject تابع جديد باسم
RopeHingeAnchor إليه . سيتم استخدام GameObject هذا لتحديد موضع التعليق / نقطة ربط خطاف القط.
إضافة مكونات
SpriteRenderer و
RigidBody2D إلى
RopeHingeAnchor .
بالنسبة لـ SpriteRenderer ، قم بتعيين خاصية
Sprite لاستخدام قيمة
UISprite وتغيير
الترتيب في الطبقة إلى
2 . قم بتعطيل المكون
بإلغاء تحديد المربع المجاور لاسمه.
لمكون
RigidBody2D ، قم بتعيين خاصية نوع الجسم إلى
Kinematic . لن يتم نقل هذه النقطة بواسطة المحرك الفعلي ، ولكن بواسطة الرمز.
حدد طبقة
الحبل واضبط قيم المقياس X و Y للمكون Transform على
4 .
حدد
Player مرة أخرى وقم بإرفاق مكون
DistanceJoint2D الجديد.
اسحب
RopeHingeAnchor من التسلسل الهرمي إلى خاصية
الجسم المتصل المتصل لمكون DistanceJoint2D وأوقف تشغيل
المسافة التلقائية للتكوين .
قم بإنشاء برنامج نصي C # جديد يسمى
RopeSystem في مجلد مشروع
البرامج النصية وافتحه في محرر التعليمات البرمجية.
قم بإزالة طريقة
Update
.
في أعلى النص البرمجي داخل
RopeSystem
فئة
RopeSystem
أضف متغيرات جديدة وأسلوب
Awake()
وأسلوب
Update
الجديد:
دعونا نحلل كل جزء بالترتيب:
- نستخدم هذه المتغيرات لتتبع المكونات المختلفة التي سيتفاعل معها البرنامج النصي RopeSystem.
- يبدأ أسلوب
Awake
في بداية اللعبة ويعطل ropeJoint
(مكون DistanceJoint2D). كما أنه يضبط playerPosition
على الوضع الحالي للاعب. - هذا هو أهم جزء من حلقة
Update()
الرئيسية. أولاً ، نحصل على وضع مؤشر الماوس في العالم باستخدام ScreenToWorldPoint
الكاميرا ScreenToWorldPoint
. ثم نحسب اتجاه نظرتنا بطرح موضع اللاعب من موضع الماوس في العالم. ثم نستخدمه لإنشاء aimAngle
، وهو تمثيل لزاوية توجيه المؤشر. تخزن القيمة قيمة موجبة في البناء إذا. aimDirection
هو تطور يأتي في وقت لاحق. نحن مهتمون فقط بقيمة Z ، نظرًا لأننا نستخدم كاميرا ثنائية الأبعاد ، وهذا هو نظام التشغيل المقابل الوحيد. نقوم بتمرير aimAngle * Mathf.Rad2Deg
، الذي يحول زاوية الراديان إلى زاوية بالدرجات.- تتم مراقبة موضع اللاعب باستخدام متغير مناسب يسمح لك بعدم الرجوع باستمرار إلى
transform.Position
. - أخيرًا ، لدينا
if..else
بناء ، والذي if..else
قريبًا لتحديد ما إذا كان الحبل مرتبطًا بنقطة الربط.
احفظ النص البرمجي وارجع إلى المحرر.
قم بإرفاق مكون
RopeSystem بكائن المشغل وتعليق المكونات المختلفة في الحقول العامة التي أنشأناها في البرنامج النصي
RopeSystem . اسحب
Player و
Crosshair و
RopeHingeAnchor إلى الحقول المناسبة:
- Rope Hinge Anchor : RopeHingeAnchor
- حبل مشترك : لاعب
- التقاطع : التقاطع
- التقاطع العفريت : التقاطع
- حركة اللاعب: لاعب
نقوم الآن بكل هذه الحسابات المعقدة ، ولكن حتى الآن لا يوجد تصور يمكن أن يظهرها في العمل. لكن لا تقلق ، سنفعل ذلك قريبًا.
افتح البرنامج النصي
RopeSystem وأضف طريقة جديدة إليه:
private void SetCrosshairPosition(float aimAngle) { if (!crosshairSprite.enabled) { crosshairSprite.enabled = true; } var x = transform.position.x + 1f * Mathf.Cos(aimAngle); var y = transform.position.y + 1f * Mathf.Sin(aimAngle); var crossHairPosition = new Vector3(x, y, 0); crosshair.transform.position = crossHairPosition; }
تضع هذه الطريقة البصر بناءً على الهدف المنقولة (القيمة العائمة التي حسبناها في
Update()
) بحيث تدور حول المشغل مع نصف قطر 1 وحدة. نقوم أيضًا بتضمين نطاق نقش متحرك في حالة عدم فعل ذلك بالفعل.
في Update()
قمنا بتغيير !ropeAttached
للتحقق !ropeAttached
بحيث يبدو مثل هذا:
if (!ropeAttached) { SetCrosshairPosition(aimAngle); } else { crosshairSprite.enabled = false; }
قم بحفظ البرنامج النصي وتشغيل اللعبة. الآن يجب أن يكون سبيكةنا قادرًا على التصويب بمنظر.
الجزء التالي من المنطق الذي يجب تنفيذه هو لقطة هوك. لقد حددنا بالفعل اتجاه التصويب ، لذلك نحتاج إلى طريقة ستستقبلها كمعلمة.
أضف المتغيرات التالية أسفل المتغيرات في البرنامج النصي
RopeSystem :
public LineRenderer ropeRenderer; public LayerMask ropeLayerMask; private float ropeMaxCastDistance = 20f; private List<Vector2> ropePositions = new List<Vector2>();
سيحتوي LineRenderer على رابط إلى عارض الخط الذي يرسم الحبل. يسمح لك
LayerMask بتخصيص طبقات الفيزياء التي يمكن أن يتفاعل معها الخطاف. تحدد قيمة
ropeMaxCastDistance
الحد الأقصى للمسافة التي يمكن لـ raycast "التقاطها".
أخيرًا ، سيتم استخدام قائمة مواقف Vector2 لتتبع نقاط التفاف الحبل ، والتي سنناقشها لاحقًا.
أضف الطرق الجديدة التالية:
إليك ما يفعله الرمز أعلاه:
- يتم استدعاء HandleInput من حلقة
Update()
ويستقصي ببساطة إدخال زري الماوس الأيمن والأيسر. - عندما يتم تسجيل النقر الأيسر ، يتم تشغيل خط الحبل ويتم إطلاق راديو ثنائي الأبعاد من موضع اللاعب في اتجاه التصويب. يتم تعيين الحد الأقصى للمسافة بحيث لا يمكن إطلاق النار على القط هوك على مسافة لا حصر لها ، ويتم تطبيق قناع بحيث يمكن تحديد طبقات الفيزياء التي يمكن أن يصطدم بها الأشعة.
- إذا تم الكشف عن إصابة شعاعية ، فإن
ropeAttached
يكون true
، ويتم التحقق من قائمة ropeAttached
الحبل للتأكد من عدم وجود نقطة هناك. - إذا كان الاختيار صحيحًا ، فسيتم إضافة دفعة صغيرة من القوة إلى البزاقة بحيث ترتد فوق الأرض ، يتم تشغيل
ropeJoint
(DistanceJoint2D) ، والذي يتم تعيينه على المسافة التي تساوي المسافة بين البزاق ونقطة ضرب الأشعة. يتم أيضًا تضمين نقش نقطة ربط. - إذا لم يضرب raycast أي شيء ، فسيتم تعطيل عارض الخط و ropeJoint ،
ropeAttached
علامة ropeAttached
خاطئة. - إذا تم الضغط على زر الماوس الأيمن ، يتم
ResetRope()
أسلوب ResetRope()
، والذي يعطل ويعيد تعيين جميع المعلمات المتعلقة بالحبل / الخطاف إلى القيم التي يجب أن تكون إذا لم يتم استخدام الخطاف.
في الجزء السفلي من طريقة
Update
بنا ، أضف مكالمة إلى طريقة
HandleInput()
الجديدة
HandleInput()
بتمرير قيمة
aimDirection
:
HandleInput(aimDirection);
احفظ التغييرات على
RopeSystem.cs والعودة إلى المحرر.
مضيفا حبل
لن يكون البزاقة الخاصة بنا قادرة على الطيران في الهواء بدون حبل ، لذا فقد حان الوقت لإعطائها شيئًا يمثل تمثيلًا بصريًا للحبل ولديه القدرة على "الدوران" حول الزوايا.
يعد عارض الخطوط مثاليًا لهذا ، لأنه يسمح لنا بنقل عدد النقاط وموضعها في مساحة العالم.
الفكرة هنا هي أننا نقوم دائمًا بتخزين الرأس الأول للحبل (0) في وضع اللاعب ، ويتم وضع جميع القمم الأخرى ديناميكيًا عندما يجب أن يلتف الحبل حول شيء ما ، بما في ذلك الموضع الحالي للمفصلة ، وهو النقطة التالية على طول الحبل من اللاعب.
حدد
Player وأضف مكون
LineRenderer إليه. اضبط
العرض على
0.075 . قم بتوسيع قائمة
المواد و ، كعنصر
0 ، حدد مواد
RopeMaterial الموجودة في مجلد
المواد بالمشروع. أخيرًا ، بالنسبة إلى Line Renderer ، لوضع
Texture ، حدد
Distribute Per Segment .
اسحب مكون Line Renderer إلى حقل
Render Renderer لمكون
نظام الحبل .
انقر على القائمة المنسدلة
لقناع طبقة الحبل وحدد طبقات يمكن أن يتفاعل معها شعاع
افتراضي وحبل ومحور. ونتيجة لذلك ، عند "تصوير" أشعة راديوية ، فإنها ستصطدم فقط بهذه الطبقات ، ولكن ليس مع الكائنات الأخرى ، مثل المشغل.
إذا بدأت اللعبة الآن ، ستلاحظ سلوكًا غريبًا. عندما نهدف إلى حجر فوق رأس البزاق ونطلق النار بخطاف ، نحصل على قفزة صغيرة لأعلى ، وبعد ذلك يبدأ صديقنا في التصرف بشكل عشوائي إلى حد ما.
لم نحدد بعد مسافة مفصل المسافة ، بالإضافة إلى ذلك ، لم يتم تكوين رؤوس تقديم الخط. لذلك ، لا نرى الحبل ، وبما أن مفصل المسافة أعلى مباشرة من موضع سبيكة ، فإن القيمة الحالية لمسافة المسافة المشتركة تدفعه إلى أسفل إلى الأحجار تحته.
لكن لا تقلق ، الآن سنحل هذه المشكلة.
في البرنامج النصي
RopeSystem.cs ، قم بإضافة عامل تشغيل جديد في بداية الفصل الدراسي:
using System.Linq;
وهذا يسمح لنا باستخدام استعلامات LINQ ، والتي تسمح لنا في حالتنا بالعثور بسهولة على العنصر الأول أو الأخير من قائمة
ropePositions
.
ملاحظة : استعلام اللغة المتكامل (LINQ) هو اسم مجموعة من التقنيات التي تعتمد على تضمين إمكانات الاستعلام مباشرة في C #. يمكنك قراءة المزيد عنها هنا .
قم بإضافة متغير خاص منطقي جديد يسمى
distanceSet
تحت المتغيرات الأخرى:
private bool distanceSet;
سنستخدم هذا المتغير كعلم حتى يتمكن البرنامج النصي من التعرف على أن مسافة الحبل (للنقطة بين اللاعب والنقطة المرجعية الحالية حيث يتم إرفاق خطاف القط) تم تعيينها بشكل صحيح.
أضف الآن طريقة جديدة
ropePositions
لتعيين مواضع رؤوس القمم لتقديم الخط وتحديد مسافة المسافة المشتركة في قائمة المواضع المخزنة بالحبل (مواقع الحبل):
private void UpdateRopePositions() {
اشرح الرمز الموضح أعلاه:
- اخرج من الطريقة إذا لم يكن الحبل مثبتًا.
- نحن نعين قيمة نقاط
ropePositions
لخط الحبل لعدد المواضع المخزنة في مواقف ropePositions
، بالإضافة إلى 1 أخرى (لموقف اللاعب). - نحن
ropePositions
حول قائمة ropePositions
لكل موضع (باستثناء الأخير) ، ونعين موضع قمة عارض الخط إلى قيمة موضع Vector2 المخزنة بواسطة فهرس الحلقة في قائمة ropePositions
. - قم بتعيين نقطة ربط الحبل الثانية من موضع نهاية الحبل ، حيث يجب أن تكون نقطة المفصلة / نقطة الربط الحالية ، أو إذا كان لدينا موضع واحد فقط للحبل ، فاجعلها نقطة الربط. لذا قمنا بتعيين المسافة بين
ropeJoint
والمسافة بين اللاعب والموضع الحالي للحبل ، والذي ننتقل ropeJoint
في الحلقة. - يعالج بناء if الحالة حيث يكون الموضع الحالي للحبل في الحلقة هو الثاني من النهاية ؛ أي النقطة التي يتصل عندها الحبل بالجسم ، أي المفصلة الحالية / نقطة الربط.
- يعالج هذا الكتلة
else
تعيين موضع الرأس الأخير للحبل إلى قيمة الوضع الحالي للاعب.
تذكر أن تضيف المكالمة
UpdateRopePositions()
في نهاية
Update()
UpdateRopePositions()
:
UpdateRopePositions();
احفظ التغييرات في البرنامج النصي وأعد تشغيل اللعبة. اجعل "مساحة صغيرة" قفزة صغيرة من خلال التصويب وإطلاق النار بخطاف على حجر فوق الشخصية. الآن يمكنك الاستمتاع بثمار عملك - تتأرجح سبيكة بهدوء فوق الأحجار.
الآن يمكنك الذهاب إلى نافذة المشهد ، حدد Player ، استخدم أداة التحريك (بشكل افتراضي ، مفتاح
W ) لتحريكها ومشاهدة كيف يتم تقديم الذروتين لخط الحبل بموقف الخطاف وموضع اللاعب لرسم الحبل. بعد تحرير المشغل ، يحسب DistanceJoint2D المسافة بشكل صحيح وسيستمر البزاق في التأرجح على المفصلة المتصلة.
معالجة نقاط الالتفاف
لا يعد اللعب باستخدام سبيكة متأرجحة مفيدًا أكثر من منشفة طاردة للماء ، لذلك نحتاج بالتأكيد إلى تكميلها.
الخبر السار هو أن الطريقة المضافة حديثًا لمعالجة مواقع الحبل يمكن استخدامها في المستقبل. حتى الآن نحن نستخدم موقعين حبل فقط. أحدهما متصل بموقف اللاعب ، والثاني بالموضع الحالي لنقطة ربط الخطاف عند إطلاق النار عليه.
المشكلة الوحيدة هي أنه بينما لا نتتبع جميع المواقف المحتملة للحبل ، وهذا يحتاج إلى القليل من العمل.
للتعرف على المواضع على الأحجار التي يجب أن يلتف حولها الحبل ، بإضافة موضع قمة جديد إلى عارض الخط ، نحتاج إلى نظام يحدد ما إذا كانت نقطة قمة المصادم بين الخط المستقيم بين الموضع الحالي للسلخ ونقطة المفصلة / نقطة الربط الحالية للحبل.
يبدو أن هذا هو العمل مرة أخرى من أجل raycast قديم جيد!
أولاً ، نحتاج إلى إنشاء طريقة يمكنها العثور على أقرب نقطة في المصادم استنادًا إلى نقطة إصابة raycast وحواف المصادم.
قم بإضافة طريقة جديدة إلى البرنامج النصي
RopeSystem.cs :
إذا لم تكن على دراية باستعلامات LINQ ، فقد يبدو هذا الرمز وكأنه نوع من السحر المعقد C #.
إذا كان الأمر كذلك ، فلا تخف. تقوم LINQ بعمل كثير لنا:
- تأخذ هذه الطريقة معلمتين - كائن RaycastHit2D وكائن PolygonCollider2D . جميع الأحجار على المستوى لها مصادمات PolygonCollider2D ، لذلك إذا استخدمنا دائمًا أشكال PolygonCollider2D ، فستعمل بشكل جيد.
- هنا يبدأ سحر الاستعلام LINQ! هنا نقوم بتحويل مجموعة نقاط المصادم المضلع إلى قاموس المواضع Vector2 (قيمة كل عنصر من عناصر القاموس هي الموضع نفسه) ، ويتم تعيين مفتاح كل عنصر قيمة المسافة من هذه النقطة إلى مشغل موضع اللاعب (القيمة العائمة). في بعض الأحيان يحدث شيء آخر هنا: يتم تحويل الموضع الناتج إلى الفضاء العالمي (بشكل افتراضي ، يتم تخزين مواضع رؤوس المصادم في الفضاء المحلي ، أي المحلي بالنسبة للكائن الذي ينتمي إليه المصادم ، ونحن بحاجة إلى مواقف في الفضاء العالمي).
- يتم فرز القاموس حسب المفتاح. بعبارة أخرى ، بالمسافة الأقرب إلى موقع اللاعب الحالي. يتم إرجاع أقرب مسافة ، أي أن أي نقطة يتم إرجاعها بهذه الطريقة هي نقطة المصادم بين اللاعب والنقطة الحالية لمفصلة الحبل!
دعنا نعود إلى البرنامج النصي
RopeSystem.cs وإضافة متغير حقل خاص جديد في الأعلى:
private Dictionary<Vector2, int> wrapPointsLookup = new Dictionary<Vector2, int>();
سنستخدمها لتتبع المواقف التي يمكن للحبل الالتفاف حولها.
في نهاية طريقة
Update()
، ابحث عن البناء
else
الذي يحتوي على
crosshairSprite.enabled = false;
ويضاف ما يلي:
اشرح هذا الجزء من الكود:
- إذا تم تخزين بعض المواقف في قائمة المواقع ، ثم ...
- نطلق النار من موضع اللاعب في اتجاه اللاعب الذي ينظر إلى الموضع الأخير للحبل من القائمة - نقطة الربط التي يتم فيها ربط خطاف القط بالحجر - بمسافة شعاع تساوي المسافة بين اللاعب وموقع نقطة ربط الحبل.
- إذا اصطدم raycast بشيء ما ، فسيتم مصادم هذا الكائن بأمان إلى نوع PolygonCollider2D . في حين أنه PolygonCollider2D حقيقي ، يتم إرجاع أقرب موضع قمة للمصادم باستخدام الطريقة التي كتبناها سابقًا باسم Vector2 .
- يتم فحصه بواسطة
wrapPointsLookup
للتأكد من أنه لم يتم التحقق من نفس الوضع مرة أخرى. إذا تم فحصه ، فإننا نتخلص من الحبل ونقطعه ، وأسقط اللاعب. - ثم يتم
ropePositions
قائمة ropePositions
: يتم إضافة الموضع الذي يلتف حوله الحبل. يتم تحديث قاموس wrapPointsLookup
أيضًا. أخيرًا ، تتم إعادة تعيين علامة distanceSet
بحيث يمكن للأسلوب UpdateRopePositions()
إعادة تعريف مسافة الحبل بالطول الجديد للحبل والمقاطع.
في
ResetRope()
أضف السطر التالي بحيث
wrapPointsLookup
مسح قاموس
wrapPointsLookup
كل مرة يقوم فيها اللاعب بقطع الحبل:
wrapPointsLookup.Clear();
حفظ وتشغيل اللعبة. قم بتصوير خطاف القطط في الحجر أعلى البزاق واستخدم أداة التحريك في نافذة المشهد لتحريك البزاق على عدة حواف حجرية.
هكذا علمنا الحبل أن يلتف حول الأشياء!
أضف قدرة هزاز
سبيكة معلقة على الحبل ثابتة للغاية. لإصلاح ذلك ، يمكننا إضافة قدرة التأرجح.
للقيام بذلك ، نحتاج إلى الحصول على موقف عمودي على موقف التأرجح للأمام (جانبي) ، بغض النظر عن الزاوية التي ينظر إليها.
افتح
PlayerMovement.cs وأضف المتغيرين العامين التاليين إلى أعلى البرنامج النصي:
public Vector2 ropeHook; public float swingForce = 4f;
سيتم تعيين متغير
ropeHook
أي موضع يوجد فيه خطاف الحبل حاليًا ، و
swingForce
هي القيمة التي نستخدمها لإضافة حركة التأرجح.
استبدل طريقة
FixedUpdate()
جديدة:
void FixedUpdate() { if (horizontalInput < 0f || horizontalInput > 0f) { animator.SetFloat("Speed", Mathf.Abs(horizontalInput)); playerSprite.flipX = horizontalInput < 0f; if (isSwinging) { animator.SetBool("IsSwinging", true);
,
isSwinging
, , , , .
- .
- , ,
playerToHookDirection
. , .
RopeSystem.cs else if(!ropeAttached)
Update()
:
playerMovement.isSwinging = true; playerMovement.ropeHook = ropePositions.Last();
في كتلة if من نفس التصميم ، if(!ropeAttached)
أضف ما يلي: playerMovement.isSwinging = false;
لذا نبلغ البرنامج النصي PlayerMovement أن اللاعب يتأرجح ، ونحدد أيضًا الموقف الأخير (باستثناء موضع اللاعب) للحبل - بعبارة أخرى ، نقطة ربط الحبل. يعد ذلك ضروريًا لحساب الزاوية المتعامدة التي أضفناها للتو إلى البرنامج النصي PlayerMovement.إليك ما يبدو إذا قمت بتشغيل الأداة في لعبة الجري واضغطت A أو D للتأرجح يسارًا / يمينًا:مضيفا نزول الحبل
بينما ليس لدينا القدرة على التحرك صعودا ونزولا على الحبل. على الرغم من أنه في الحياة الواقعية لا يمكن أن يرتفع البزاق ويسقط بسهولة على طول الحبل ، ولكن هذه لعبة يمكن أن يحدث فيها أي شيء ، أليس كذلك؟في الجزء العلوي من البرنامج النصي RopeSystem ، أضف متغيرين حقلين جديدين: public float climbSpeed = 3f; private bool isColliding;
climbSpeed
سيحدد السرعة التي يمكن أن يتحرك بها البزاق لأعلى وأسفل الحبل ، isColliding
وسيتم استخدامه كعلم لتحديد ما إذا كان يمكن زيادة أو تقليل خاصية وصلة المسافة لحبل وصلة المسافة.أضف هذه الطريقة الجديدة: private void HandleRopeLength() {
if..elseif
(/ W/S ),
ropeAttached iscColliding
ropeJoint
, .
,
Update()
:
HandleRopeLength();
isColliding
.
:
void OnTriggerStay2D(Collider2D colliderStay) { isColliding = true; } private void OnTriggerExit2D(Collider2D colliderOnExit) { isColliding = false; }
هاتان الطريقتان هما طريقتان أصليتان للفئة الأساسية من نصوص MonoBehaviour.إذا لامس Collider حاليًا كائنًا ماديًا آخر في اللعبة ، فسيتم إطلاق الطريقة باستمرار OnTriggerStay2D
، وتعيين isColliding
قيمة للعلم true
. هذا يعني أنه عندما يلمس سبيكة الحجر ، يتم تعيين العلم isColliding قيمة true
.يتم OnTriggerExit2D
تشغيل الطريقة عندما يغادر مصادم منطقة مصادم آخر ، مما يؤدي إلى تعيين العلم على false.ضع في اعتبارك: OnTriggerStay2D
قد تكون الطريقة مكلفة للغاية من الناحية الحسابية ، لذا استخدمها بعناية.إلى أين أذهب بعد ذلك؟
ابدأ اللعبة مرة أخرى وهذه المرة اضغط على مفاتيح الأسهم أو W / S للتحرك لأعلى وأسفل الحبل.يمكن تنزيل المشروع النهائي لهذا الجزء من البرنامج التعليمي هنا .لقد قطعنا شوطًا طويلاً - من الرخويات غير المتأرجحة إلى الرخويات البهلوانية الخالية من القشرة البهلوانية!لقد تعلمت كيفية إنشاء نظام تصويب يمكنه إطلاق خطاف القط على أي شيء يحتوي على مصادم ، والتشبث به والتأرجح عليه في نفس الوقت ، واستدارة حبل ديناميكي حول حواف الأشياء! عمل عظيم.ومع ذلك ، هناك وظيفة مهمة مفقودة هنا - لا يمكن للحبل "الاسترخاء" عند الضرورة.في الجزء الثاني من البرنامج التعليمي سنقوم بحل هذه المشكلة.ولكن إذا كنت على استعداد لاغتنام الفرصة ، فلماذا لا تحاول القيام بذلك بنفسك؟ يمكنك استخدام قاموس لهذا wrapPointsLookup
.