القائمة الرئيسية

الصفحات

Unity Game Engine: جعل الكائن يتحرك وتحديد السرعة

Unity Game Engine: جعل الكائن يتحرك وتحديد السرعة
 

Unity Game Engine: جعل الكائن يتحرك وتحديد السرعة 

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

ملاحظة:
 من الطرق الرائعة للاختبار ، في حالة وجود مبنى جاهز ، 
مجرد إلقاء نظرة على اسم كائن gameObject في التسلسل الهرمي . 
كائنات اللعبة التي تحتوي على مبنى جاهز موجود لها سيكون اسمها مكتوبًا باللون الأزرق.



الآن ، سنمضي قدمًا وننشئ نصًا جديدًا باسم Shooter.


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

public class Shooter : MonoBehaviour
{
    public GameObject fireball;
    public RigidBody2D body;
    public float speed;
    
    void Update() 
    {
        body.velocity = new Vector2(Input.GetAxisRaw("Horizontal")*speed, Input.GetAxisRaw("Vertical")*speed);
        
        // When spacebar is hit
        if(Input.GetKeyDown(KeyCode.Space))
        {
            // instantiate the fireball object
            Instantiate(fireball);
        }
    }

}


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


تحديد الموقف للمباني الجاهزة الجديدة

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

Unity Game Engine: جعل الكائن يتحرك وتحديد السرعة

أعلاه هو الحمل الزائد الافتراضي (التباين) Instantiate للطريقة التي استخدمناها حتى الآن.
 دعنا ننتقل عبر الأحمال الزائدة لمعرفة أي منها قد نجد مفيدًا.

Unity Game Engine: جعل الكائن يتحرك وتحديد السرعة

تأخذ طريقة overload (variation) أعلاه مثيل Object(gameObject)
 كوسيطة لتوليدها ومثالًا Vector3 كوسيطة لتحديد مكان إنشائها!
 في احسن الاحوال. لا تقلق بشأن Quaternion قيمة الوسيطة ،
 فسنقوم ببساطة بتعيينها على 0.

الآن دعنا نبتعد عن لعبتنا قليلاً ، ونتحدث عن gameObject بشكل عام.
 أي كائن gameObject عادي له خاصية الموضع ، والتي يتم تخزينها كعناصر 
Vector2 ثنائية الأبعاد (أو Vector3 للعناصر ثلاثية الأبعاد). 
يمكن الوصول إلى خاصية هذا المنصب من خلال ما يلي :


// For X
gameObject.transform.position.x
// For Y
gameObject.transform.position.y




يتم تخزين كل من هذه القيم كملف float. 
إذا تمكنا من قراءة هذه القيم لشخصيتنا الرئيسية (Shooting ) ،
 فيمكننا معرفة الموضع الدقيق لشخصيتنا عند الضغط على مفتاح المسافة ،
 لإطلاق كرة نارية ، ثم ننتج كرة نارية جديدة هناك. 
نحتاج إلى التقاط x, y إحداثيات الشخصية الرئيسية في كل مرة ،
 لأنه يمكن نقل شخصيتنا باستخدام مفاتيح الأسهم.
لذلك ، دعنا نستخدم طريقة التحميل الزائد بدلاً من Instantiate() الطريقة الافتراضية .
 استبدل Instantiate() الطريقة القديمة بهذه الطريقة في نص الحرف واحفظه ا:

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

public class Shooter : MonoBehaviour
{
    public GameObject fireball;
    public RigidBody2D body;
    public float speed;
    
    void Update() 
    {
        body.velocity = new Vector2(Input.GetAxisRaw("Horizontal")*speed, Input.GetAxisRaw("Vertical")*speed);
        
        // When spacebar is hit
        if(Input.GetKeyDown(KeyCode.Space))
        {
            // instantiate the fireball object
            Instantiate(fireball,
                new Vector3(gameObject.transform.position.x, gameObject.transform.position.y, 0),
                new Quaternion(0, 0, 0, 0));
        }
    }

}




فما هو بالضبط ما يحدث هنا؟ 
حسنًا ، تأخذ طريقتنا الجديدة ذات التحميل الزائد ثلاث معاملات :

GameObject :
 كائن gameObject المراد إنشاؤه.
Vector3 : 
مكان إنشاء gameObject في مساحة ثلاثية الأبعاد.
Quaternion 
البيانات المتعلقة بتدوير كائن gameObject في مساحة ثلاثية الأبعاد.

الآن ، نظرًا لأننا نعمل في بيئة ثنائية الأبعاد ، فإننا ببساطة نأخذ في الاعتبار 
أي قيم ثلاثية الأبعاد ، أي Z القيمة التي يجب أن تكون 0.
 ستلاحظ أننا استخدمنا gameObject.transform.position في الكود. 
gameObject يشير المصطلح ببساطة إلى كائن gameObject المرفق بالبرنامج النصي حاليًا. 
وهذا يعني في حالتنا أن gameObject تشير إلى شخصيتنا الرئيسية وهي Shooting .
السطر 20:
 نقوم بإنشاء عنصر جديد Vector3 يتكون من ثلاثة عناصر. 
هذه العناصر الثلاثة هي X، Yو Z إحداثيات الموقع حيث يتم إنشاء ناري.
ما نقوم به هنا هو إخبار اللعبة بشكل أساسي بإنشاء كائن كرة نارية جديد
 في الموقع المحدد حيث كان اللاعب عندما ضغط على مفتاح المسافة.
قمنا بتعيين قيم كواترنيون Quaternion
 (التي تأخذ 4 معلمات ، x و y، وقيمة z إضافية w) على الصفر ، لأنها معقدة حقًا. 
في الواقع ، حتى دليل Unity الرسمي ينص على أنه لا ينبغي عليك 
التعامل معهم إلا إذا كنت تعرف ما تفعله.

لماذا نقوم حتى بإنشاء أياً كان (Quaternion) في المقام الأول؟

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

نقل المباني الجاهزة الجديدة فور إنشائها

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


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

public class FireballBehaviour : MonoBehaviour
{
    private float fireballXValue;
    public float fireballSpeed;
    
    void Start()
    {
        // getting the initial position where prefab is created
        fireballXValue = gameObject.transform.position.x;
    }
    
    // Update is called once per frame
    void Update() 
    {
        // adding speed value to the X axis position
        // value
        fireballXValue += fireballSpeed;
        // setting new X value to position
        gameObject.transform.position = new Vector2(fireballXValue, gameObject.transform.position.y);
        }
    }

}




انظر ماذا نفعل هنا؟ استخدمنا متغيرًا عائمًا خاصًا 
(لا نريد حقًا أن ترى البرامج النصية الأخرى هذه x القيمة) 
مُسمى fireballXvalue لتخزين X قيمة موضع كرة النار.

عندما نقوم بتهيئة كرة نارية جديدة ، فإن كرة نارية جديدة تعمل start() بوظيفتها
 (تذكر أن start() الوظيفة يتم تشغيلها مرة واحدة في البداية 
عندما gameObject تصبح نشطة وممكّنة).
 ما نقوم به هو تحديد القيمة fireballXvalue على X قيمة 
موضع الكائن في لحظة بدء تشغيله. 
سيؤدي هذا إلى التأكد من أن كرة النار تبدأ في التحرك من النقطة التي نطلقها ،
 وليس من المركز الميت.

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



ملاحظة: لقد حاولنا تغيير x قيمة المركز مباشرة في السطر 22.

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

يضبط قيمة متغير جديد تمامًا يسمى fireballXvalue الموضع الأولي للرصاصة.
يضيف قيمة speed إلى fireballXvalue كل إطار.
يضبط موضع الرصاصة في كل إطار fireballXvalue ونفس Y القيمة كما كانت
 (لا نريد أن تتحرك كرة النار عموديًا ، ولكن أفقيًا فقط).
احفظ هذا النص ، ودعنا نعود إلى Unity . 
الآن ، بما أننا نريد أن يكون لكل كرة نارية جديدة هذا البرنامج النصي ،
 فلماذا لا تضيفه ببساطة إلى القالب ؟ 
للقيام بذلك ، ما عليك سوى النقر فوق مبنى كرة النار الجاهز . 
ستلاحظ أنه يمكنك تغيير المكونات والخصائص تمامًا مثل
 كائن gameObject العادي والنشط.
 سيتم بعد ذلك تطبيق التغييرات التي تجريها هنا على كل كائن gameObject جديد 
تم إنشاؤه من هذا المبنى الجاهز ، مما يعني أنه إذا قمت بإرفاق البرنامج النصي
 بمصنع كرة النار ، فستحتوي كل كرة نارية تم إنشاؤها على
 هذا البرنامج النصي ، تمامًا كما هو الحال في المباني الجاهزة.

لذلك ، دون إضاعة المزيد من الوقت ، قم بإرفاق FireballBehaviour
 البرنامج النصي بالمبنى الجاهز للكرة النارية ، 
وقم بتعيين قيمة السرعة (نقترح شيئًا ما حول 0.4 إذا كنت تريد أن ترى الرصاص
 يتحرك بالفعل ولا تجعله يطير من على الشاشة). ياي! 
إذا أطلقنا النار باستخدام مفتاح المسافة ، فستتحرك كراتنا النارية باستمرار نحو اليمين.

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


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